staging.inyokaproject.org

Rekursiv mit Ausgabe von find

Status: Gelöst | Ubuntu-Version: Kubuntu 18.04 (Bionic Beaver)
Antworten |

JOberst

Anmeldungsdatum:
2. März 2012

Beiträge: 204

Hallo! Ich habe bisher keine große Erfahrung mit bash-skripting. Jetzt versuche mich gerade an einem kleinen Skript, um rekursiv Dateien zu manipulieren.

Die Ausgabe von

find . -iname "*.endung"

gibt korrekt alle Dateien mit .endung aus, inklusive denen in Unterverzeichnissen.

Mit

find . -iname "*.endung" |
    for file in ./*/*endung ; do

werden die Unterverzeichnisse nicht bearbeitet.

Wie setze ich den Parameter korrekt, um alle Dateien zu bearbeiten?

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4453

Was möchtest Du denn machen? Schau Dir mal den -exec Parameter von find an. Der ist eigentlich für so etwas gedacht...

Und wenn Du das doch in eine Schleife pipen möchtest, dann musst Du wohl eher "while read line; do" verwenden...

JOberst

(Themenstarter)

Anmeldungsdatum:
2. März 2012

Beiträge: 204

Doc_Symbiosis schrieb:

Was möchtest Du denn machen? Schau Dir mal den -exec Parameter von find an. Der ist eigentlich für so etwas gedacht...

Ich möchte eine XML-Datei bearbeiten, mit sed hauptsächlich. Oder mit xmlstarlet. Das hab ich bisher mit -exec nicht hingekriegt.

Und wenn Du das doch in eine Schleife pipen möchtest, dann musst Du wohl eher "while read line; do" verwenden...

Wie sähe das aus? Ich verwende ja $file als Variable für die weitere Bearbeitung.

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4453

Zum Beispiel so:

find . -iname "*.endung" -exec sed -i 's/l/r/g' {} \;

Das ersetzt direkt in allen gefunden Dateien alle l durch r. Das {} steht hier für den Dateinamen.

Alternativ kannst Du auch xargs verwenden:

 find . -iname "*.endung" | xargs sed -i 's/l/r/g'

JOberst

(Themenstarter)

Anmeldungsdatum:
2. März 2012

Beiträge: 204

Doc_Symbiosis schrieb:

Zum Beispiel so:

find . -iname "*.endung" -exec sed -i 's/l/r/g' {} \;

Das ersetzt direkt in allen gefunden Dateien alle l durch r. Das {} steht hier für den Dateinamen.

Alternativ kannst Du auch xargs verwenden:

 find . -iname "*.endung" | xargs sed -i 's/l/r/g'

Okay - und wenn ich $file für sed benötige? Bisher hatte ich es so:

sed -ri '4s|(<OutputFilename>).*/(.*.jpg)|\1\2|' $file

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Doc_Symbiosis schrieb:

Zum Beispiel so:

find . -iname "*.endung" -exec sed -i 's/l/r/g' {} \;

Das ersetzt direkt in allen gefunden Dateien alle l durch r. Das {} steht hier für den Dateinamen.

Das kann man noch effizienter machen, so dass nur alle n Dateien ein sed gestartet wird:

1
find -type f -iname '*.endung' -exec sed -i 's/l/r/g' {} +

Alternativ kannst Du auch xargs verwenden:

 find . -iname "*.endung" | xargs sed -i 's/l/r/g'

Dann aber bitte so, damit es keine Probleme mit Sonderzeichen in Dateinamen gibt und auch für den Fall, dass keine Datei gefunden wird.

1
find -type f -iname '*.endung' -print0 | xargs -r0 sed -i 's/l/r/g'

JOberst

(Themenstarter)

Anmeldungsdatum:
2. März 2012

Beiträge: 204

rklm schrieb:

Doc_Symbiosis schrieb:

Zum Beispiel so:

find . -iname "*.endung" -exec sed -i 's/l/r/g' {} \;

Das ersetzt direkt in allen gefunden Dateien alle l durch r. Das {} steht hier für den Dateinamen.

Das kann man noch effizienter machen, so dass nur alle n Dateien ein sed gestartet wird:

Das funktioniert beides rekursiv, so wie ich es brauche. Aber ich habe bisher mit sed den Dateinamen geschrieben, eben das $file aus

find . -iname "*.endung" |
    for file in ./*/*endung ; do  

Das geht ja nun in diesen Varianten leider nicht mehr.

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4453

Wohin möchtest Du den Dateinamen schreiben? ich verstehe dein Problem leider nicht so ganz.

JOberst

(Themenstarter)

Anmeldungsdatum:
2. März 2012

Beiträge: 204

Doc_Symbiosis schrieb:

Wohin möchtest Du den Dateinamen schreiben? ich verstehe dein Problem leider nicht so ganz.

Ich möchte (u.a.) das Name aus Name.endung in die 4. Zeile schreiben, die dann so aussehen soll:

<OutputFilename>Name.jpg</OutputFilename>

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

JOberst schrieb:

Doc_Symbiosis schrieb:

Wohin möchtest Du den Dateinamen schreiben? ich verstehe dein Problem leider nicht so ganz.

Ich möchte (u.a.) das Name aus Name.endung in die 4. Zeile schreiben, die dann so aussehen soll:

<OutputFilename>Name.jpg</OutputFilename>

Also Du brauchst noch mehr Verarbeitungsschritte pro Datei. Dann eher so etwas:

1
2
3
4
5
6
7
find -type f -name '*.foo' -exec sh -c '
for file; do
  name="${file##*/}"
  name="${name%.*}"
  sed -i "4s#^.*\$#<OutputFilename>${name}</OutputFilename>#" "$file"
done
' -- {} +

JOberst

(Themenstarter)

Anmeldungsdatum:
2. März 2012

Beiträge: 204

Jaaa, das klappt! Super, danke 👍

Antworten |