GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Entferne unbekannte Zeichen aus Zeichenfolge für -exec?

Ich habe einen Suchbefehl, der bestimmte Dateien und Verzeichnisse findet. Dieser Suchbefehl führt dann rsync mit den zuvor gefundenen Dateien und Verzeichnissen als Quelle aus. Das Problem ist, dass diese Dateien und Verzeichnisse alle möglichen Zeichen wie einfache und doppelte Anführungszeichen enthalten können, ganz zu schweigen von illegalen Zeichen von Windows usw.

Wie kann ich einen String dynamisch maskieren, um ihn in rsync oder anderen Befehlen zu verwenden?

Dieser Befehl funktioniert, indem doppelte Anführungszeichen für die rsync-Quellzeichenfolge fest codiert werden, aber es bricht ab, wenn die Zeichenfolge doppelte Anführungszeichen enthält.

find "/mnt/downloads/cache/" -depth -mindepth 1 \( \
-type f \! -exec fuser -s '{}' \; -o \
-type d \! -empty \) \
\( -exec echo rsync -i -dIWRpEAXogt --numeric-ids --inplace --dry-run '"{}"' "${POOL}" \; \)

resultierende Ausgabe:

rsync -i -dIWRpEAXogt --numeric-ids --inplace --dry-run "test/this " is an issue" /mnt/backing

Arbeitsbefehl nach Info in Antworten angewendet:

find "/mnt/downloads/cache/" -depth -mindepth 1 \( \
                             -type f \! -exec fuser -s {} \; -o \
                             -type d \! -empty \) \
                             \( -exec rsync -i -dIWRpEAXogt --remove-source-files-- "${POOL} \; \) \
                             -o \( -type d -empty -exec rm -d {} \; \)

Akzeptierte Antwort:

Ihr Zitierproblem kommt daher, dass Sie versuchen, ein Problem zu lösen, das Sie gar nicht haben. Die Notwendigkeit, Argumente in Anführungszeichen zu setzen, kommt nur ins Spiel, wenn Sie es mit einer Shell zu tun haben und wenn find ruft rsync auf direkt, es ist keine Shell beteiligt. Die Verwendung einer visuellen Ausgabe ist keine gute Möglichkeit, um festzustellen, ob es funktioniert oder nicht, da Sie nicht sehen können, wo jedes Argument beginnt und endet.

Folgendes meine ich:

# touch "foo'\"bar"

# ls
foo'"bar

# find . -type f -exec stat {} \;
  File: ‘./foo'"bar’
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 1659137     Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1004/ phemmer)   Gid: ( 1004/ phemmer)
Access: 2017-12-09 13:21:28.742597483 -0500
Modify: 2017-12-09 13:21:28.742597483 -0500
Change: 2017-12-09 13:21:28.742597483 -0500
 Birth: -

Beachten Sie, dass ich den {} nicht zitiert habe im Argument zu stat .

Nun, das heißt, Ihr Befehl wird sehr leistungsschwach sein, weil Sie rsync aufrufen für jede einzelne passende Datei. Es gibt zwei Möglichkeiten, wie Sie dies lösen können.

Wie andere angedeutet haben, können Sie die Dateiliste an rsync weiterleiten auf stdin:

# find . -type f -print0 | rsync --files-from=- -0 . dest/

# ls dest/
foo'"bar

Dies verwendet Null-Bytes als Dateinamen-Trennzeichen, da Dateien keine Null-Bytes in ihrem Namen enthalten dürfen.

Verwandte Themen:Wie behebt man den Fehler „Unbekanntes USB-Gerät benötigt mehr Strom, als der Anschluss liefern kann“?

Wenn Sie GNU find verwenden , haben Sie eine andere Methode zum Aufrufen von -exec , und das ist -exec {} + . In diesem Stil find wird mehr als ein Argument gleichzeitig übergeben. Alle Argumente werden jedoch am Ende des Befehls hinzugefügt, nicht in der Mitte. Sie können dies angehen, indem Sie die Argumente durch eine kleine Shell leiten:

# find . -type f -exec sh -c 'rsync "[email protected]" dest/' {} +

# ls dest/
foo'"bar

Dadurch wird die Liste der Dateien an sh übergeben wodurch sie dann durch den "[email protected]" ersetzt werden


Linux
  1. Tr Analog für Unicode-Zeichen?

  2. Wofür stehen Sonderzeichen in Echo {a..z}?

  3. Die Option -exec in Find zum Laufen bringen?

  4. find -exec cmd {} + vs | xargs

  5. Wie finde ich den vollständigen Pfad des C++-Linux-Programms von innen heraus?

So finden Sie eine Zeichenfolge in einer Datei unter Linux

So suchen Sie nach Dateien über die Linux-Befehlszeile

So entfernen Sie (^M) Zeichen aus einer Datei in Linux

Pipe-String zum GNU-Datum für die Konvertierung - wie kann man es von stdin lesen lassen?

Entfernen Sie alle Sonderzeichen und Groß-/Kleinschreibung aus der Zeichenfolge in Bash

grep, um Dateien zu finden, die eine Zeichenfolge enthalten, die länger als x Zeichen ist?