2016-05-25 3 views
1

Ich möchte eine Suche in einigen dir, und tun Sie eine awk für die Dateien in diesem Verzeichnis, und ersetzen Sie dann die ursprünglichen Dateien durch jedes Ergebnis.Finden Sie die Dateinamen der gefundenen Dateien in die Pipe?

find dir | xargs cat | awk ... | mv ... > filename 

Also ich brauche den Dateinamen (von jeder der gefundenen Dateien von find) im letzten Befehl. Wie kann ich das machen?

+0

Welches Problem hast du dabei? –

+1

schreiben Sie ein Skript und übergeben Sie den Dateinamen 'find dir -exec myscript {} \;' wo myscript beginnt mit wie 'name =" $ 1 "' und das macht die Katze, die awk etc. –

+0

'xargs cat' hier ist sinnlos (und wird nicht funktionieren, weil es Dateien kombinieren wird). 'xargs awk' wäre besser (und würde' awk' jede Datei unabhängig behandeln, einschließlich 'mv', wenn Sie wirklich wollen). –

Antwort

0

würde ich eine Schleife verwenden, wie:

for filename in `find . -name "*test_file*" -print0 | xargs -0` 
do 
    # some processing, then 
    echo "what you like" > "$filename" 
done 

EDIT: wie in den Kommentaren erwähnt, werden die Vorteile der -print0 | xargs -0 wegen der for Schleife verloren. Und Dateinamen mit Leerzeichen werden immer noch nicht korrekt behandelt.

Die folgende while Schleife nicht ungewöhnlich Dateinamen umgehen würde weder (gut, es zu wissen, obwohl es nicht in der Frage war), aber Dateinamen mit einem Standard-weißen Raum zumindest, so funktioniert es besser, in der Tat:

find . -name "*test*file*" -print > files_list 

while IFS= read -r filename 
do 
    # some process 
    echo "what you like" > "$filename" 
done < files_list 
+0

Ich weiß, aber ich habe mich gefragt, ob Sie dies tun können, indem Sie mit 'find dir', nicht mit' für f in $ (find dir) ' – ericj

+0

Vielleicht können Sie diese Genauigkeit in Ihrer Frage hinzufügen? Ohne die Dateinamen irgendwo zu speichern, weiß ich nicht, wie man sie nach mehreren Befehlen zurückbekommt. – zezollo

+0

'finde dir | während lese dateiname wird sich sehr ähnlich verhalten und * beginnt * mit find dir - aber zezollos antwort deckt z. mit Zeilenumbrüchen in Dateinamen, die damit nicht umgehen würden - aber niemand versteht wirklich, warum Sie "find dir" beginnen wollen. " –

0

Sie könnte so etwas tun (aber ich würde es überhaupt nicht empfehlen).

find dir -print0 | 
    xargs -0 -n 2 awk -v OFS='\0' '<process the input and write to temporary file> 
     END {print "temporaryfile", FILENAME}' | 
    xargs -0 -n 2 mv 

Dies geht um die Dateien zu awk direkt zwei zu einer Zeit (die das Problem mit Ihrem ursprünglichen vermeidet, wo cat Hunderte (vielleicht mehr) Dateien als Argumente auf einmal und spucken alle ihren Inhalt an awk bekommen über Standard-Input sofort und verlieren somit ihre individuellen Inhalte und Dateinamen vollständig).

Es hat dann awk die verarbeitete Ausgabe in eine temporäre Datei zu schreiben, und gibt dann den temporären Dateinamen und den ursprünglichen Dateinamen, wo xargs ihnen aufgreift (wieder zwei auf einmal) und läuft mv auf den Paaren der temporären Datei/ursprüngliche Datei Namen.

Wie ich schon am Anfang sagte, ist dies jedoch ein schrecklicher Weg, dies zu tun.

Wenn Sie eine neue Version von genug GNU awk (Version 4.1.0 oder höher), dann können Sie nur die Verwendung -i (in-place) Argument awk und verwenden (glaube ich):

find dir | xargs awk -i '......' 

Ohne das würde ich eine while Schleife des Formulars in Bash FAQ 001 verwenden, um die find Ausgabe Linie-für-Linie zu lesen und auf ihr in der Schleife zu arbeiten.

Verwandte Themen