2017-08-07 3 views
1

Ich versuche, eine Shell-Skripte zu schreiben, die jede Datei in einem Verzeichnis sichern wird. In oder bekommen die Dateien, die ich verwendenErsetzen '' mit '' in Bash

FILENAMES="$(find -maxdepth 1 -not -path './.*' -type f)" 

, die alle etwas gibt die Namen der Dateien enthält.

Falls keine der Dateinamen Leerzeichen enthalten dann

tar --exclude='archive.tar.bz2' -cvpjf archive.tar.bz2 $FILENAMES 

mit macht den Job und alles ist in Ordnung.

Wenn es jedoch einen Dateinamen "bad filename.txt" gibt, funktioniert der obige Ansatz nicht und tar wird sich beschweren, dass es "schlecht" von "filename.txt" nicht finden kann.

Ich habe versucht, dieses Problem zu beheben, indem einen Inline-Ersatz, wie here verwenden, aber das funktioniert nicht:

TOARCHIVE=${FILENAMES// /'\ '} 

Im Grunde das, was tut, ist die Räume in der geeigneten Position zu ersetzen, wenn ich es echo. Aber tar scheint die eingefügte '\' nicht zu sehen. Wenn Sie versuchen, den Ersatzcode mit zwei Schrägstrichen, wie '\\' oder '\\ 'tar wird beide Schrägstriche sehen und erneut beschweren.

Eine andere Lösung für ähnliche Probleme, die ich gesehen habe, war sicherzustellen, dass alles in Anführungszeichen steht, aber das funktioniert nicht für mich, da TOARCHIVE die Namen mehrerer Dateien enthält.

+0

Möglicherweise möchten Sie nul Separator https://www.gnu.org/software/tar/manual/html_node/nul.html verwenden - und Pass '-print0' zu finden. – ideasman42

Antwort

0

Für Zeichen Ersatz, ich schlage vor, Sie sed, wie diese zu verwenden:

sed "s/\ /\\/g" myfile.txt 

Diese alle Räume in myfile.txt von einem Ich würde \

0

ersetzen wird vorschlagen, einfach nicht ' ' mit '\ ' ersetzen, wenn Sie möchten Pfade korrekt angeben.

Entweder:

  • Verwenden nul Terminatoren (-print0 Argument zu finden)
  • finden die Wege printf verwenden.

Obwohl es nicht genau das, was Ihr fragen, zitiert richtigen Pfad getan werden kann printf '%q', zB:

FILENAMES="$(
    find -maxdepth 1 -not -path './.*' -type f -print0 | 
    xargs -0 printf '%q\n' 
)" 

Dies ist nützlich, weil es andere seltsame Zeichen in Dateipfaden bedeutet, wird nicht später zu Problemen führen.

Wenn einige schwierige Person läuft touch "foo\ bar.txt" zum Beispiel :)

0

Eine Möglichkeit, es zu tun ist, um die tar-Utility ausführen von selbst finden:

find -maxdepth 1 -not -path './.*' -type f -exec tar --exclude='archive.tar.bz2' -cvpjf archive.tar.bz2 "{}" + 
+1

Dies funktioniert nicht für Dateinamen, die Anführungszeichen enthalten – ideasman42

+0

@ ideasman42 Richtig. Ich glaube, dass das oben genannte den Job macht. – Sakis

0
FILENAMES="$(find -maxdepth 1 -not -path './.*' -type f -printf "'"%f"'")" 

Drucken jeder Dateinamen von einzelnen Zitaten umgeben .

0

Speichern Sie keine Liste von Dateinamen in einem regulären Parameter. Verwenden Sie stattdessen einen Array-Parameter. Sie brauchen nicht entweder find; Ein einfacher Glob entspricht den gleichen Dateien.

filenames=(*) # assuming there are no subdirectories in the current directory 

auszuschließen Verzeichnisse (und andere nicht-reguläre Dateien), eine Shell-Schleife:

filenames=() 
for f in *; do 
    [[ -f $f ]] && filenames+=("$f") 
done 

Sobald das Array gefüllt ist, sie so

tar --exclude='archive.tar.bz2' -cvpjf archive.tar.bz2 "${filenames[@]}" 

Wenn Sie einen komplexeren Aufruf an find hätten, würde ich einfach die Null-terminierte Liste des gefundenen Dateinamensverzeichnisses anübergeben, ohne sie vorher zu speichern (vorausgesetzt, GNU tar jedenfalls):

find ... -print0 | tar --null -T - --exclude 'archive.tar.bz2' -cvpjf archive.tar.bz2 
Verwandte Themen