Windows-Dateipfad in Linux-Dateipfad konvertiert

13

Ich habe einen Windows-Pfad in einer Bash-Variablen als Zeichenfolge:

file='C:\Users\abcd\Downloads\testingFile.log'

Ich versuche, diesen Pfad in einen Linux-Pfad umzuwandeln, der mit beginnt /c/Users....

Mein Versuch

Die folgenden Arbeiten:

file=${file/C://c}
file=${file//\\//}
echo $file
> /c/Users/abcd/Downloads/testingFile.log

Problem

Hier habe ich das für einen String gemacht, der den Dateipfad enthält. Der Grund, warum ich diese Frage stelle, ist, dass ich 20 solcher Zeichenfolgen in einem Bash-Skript in Ubuntu 16.04 konvertieren muss und jedes Mal, wenn ich dies tue, 2 Zeilen pro Konvertierung schreiben muss - das nimmt viel Platz in Anspruch!

Frage

Gibt es eine Möglichkeit, die 2 Befehle zu kombinieren

file=${file/C://c}
file=${file//\\//}

in einen Befehl?

edesz
quelle
1
Verwenden Sie eine for-Schleife (und möglicherweise ein Array). Zitieren Sie auch Ihre Variablen.
wjandrea
Vielen Dank. Können Sie ein Beispiel dafür zeigen, wie dies in einer Schleife oder einem Array durchgeführt wird?
Edesz

Antworten:

17

Es gibt eine Möglichkeit, beide Ersetzungen gleichzeitig durchzuführen sed, dies ist jedoch nicht erforderlich.

So würde ich dieses Problem lösen:

  1. Fügen Sie die Dateinamen in das Array ein
  2. Über Array iterieren

filenames=(
  'C:\Users\abcd\Downloads\testingFile.log'
  # ... add more here ...
)

for f in "${filenames[@]}"; do
  f="${f/C://c}"
  f="${f//\\//}"
  echo "$f"
done

Wenn Sie die Ausgabe in ein Array einfügen möchten, anstatt sie zu drucken, ersetzen Sie die echoZeile durch eine Zuweisung:

  filenames_out+=( "$f" )
wjandrea
quelle
Ok. Aber wenn ich 2 Dateien hätte f1und f2wie würde das funktionieren? Ich meine, wie kann ich dem Array die neuen Dateinamen zuweisen, indem ich die alten ersetze?
Edesz
@WR setze sie in ein neues Array und benutze das.
muru
@WR Fügte das zur Antwort hinzu
wjandrea
1
Ich würde empfehlen, aus Gründen der Übersichtlichkeit ein neues Array zu erstellen.
wjandrea
9

Wenn es etwas ist, das Sie oft tun möchten, warum dann nicht eine kleine Shell-Funktion erstellen?

win2lin () { f="${1/C://c}"; printf '%s\n' "${f//\\//}"; }

$ file='C:\Users\abcd\Downloads\testingFile.log'
$ win2lin "$file"
/c/Users/abcd/Downloads/testingFile.log
$ 
$ file='C:\Users\pqrs\Documents\foobar'
$ win2lin "$file"
/c/Users/pqrs/Documents/foobar
Stahlfahrer
quelle
Das ist keine schlechte Idee. Es scheint jedoch nicht zu geben /c/Users...- stattdessen gibt es C:\Users\....
Edesz
@ WR Entschuldigung - Copy-Paste-Fehler. Bitte versuchen Sie es jetzt.
Steeldriver
1
Danke, ich benutze cdw () { f="${1/D://d}"; cd "/mnt${f//\\//}"; }im Windows-Subsystem für Linux, funktioniert wie ein Zauber!
Wochenende
2

Mit sed können Sie dies in einer Zeile erreichen

file="$(echo "$file" | sed -r -e 's|^C:|/c|' -e 's|\\|/|g')"

Beachten Sie, dass die beiden Muster dennoch getrennt bleiben müssen, da die Übereinstimmungen durch unterschiedliche Substitutionen ersetzt werden.

taifwa
quelle
1
Synonym:file="$(sed 's|^C:|/c|; s|\\|/|g' <<< "$file")"
wjandrea
1

Ist diese Frage noch offen für neue Vorschläge? Wenn ja, würde Ihnen das helfen?

$ file="/$(echo 'C:\Users\abcd\Downloads\testingFile.log'|tr '\\' '/')"
$ echo $file
/C:/Users/abcd/Downloads/testingFile.log

Oh, und falls das C in Kleinbuchstaben umgewandelt werden muss:

file="/$(echo 'C:\Users\abcd\Downloads\testingFile.log'|tr '^C' 'c'|tr '\\' '/')"

Zur Übersicht:

$ file='C:\Users\abcd\Downloads\testingFile.log'
$ echo $file
C:\Users\abcd\Downloads\testingFile.log
$ file="/$(echo $file|tr '^C' 'c'|tr '\\' '/')"
$ echo $file
/c:/Users/abcd/Downloads/testingFile.log

quelle
Was ist der Grund für die Verwendung '^C'?
Edesz
1
^ bedeutet Zeilenanfang, andernfalls werden alle Vorkommen von C in Kleinbuchstaben umgewandelt ... sollte es welche geben
Ich muss hinzufügen, dass die anderen Vorschläge auch funktionieren. Viele Unix-Befehle können die gleiche Aufgabe übernehmen. Es liegt also an Ihnen, welchen Lösungsstil Sie bevorzugen.
Ich hatte vorher nicht danach gefragt ^, was hier auch in einigen anderen Antworten verwendet wurde. Danke für die Antwort und die Erklärung.
Edesz