9 Stimmen

Wie kann ich Dateien in einem Unterverzeichnis mit Unix find execute und cat zu einer einzigen Datei zusammenfügen?

Ich kann das tun:

$ find .
.
./b
./b/foo
./c
./c/foo

Und dies:

$ find . -type f -exec cat {} \;
This is in b.
This is in c.

Aber nicht das:

$ find . -type f -exec cat > out.txt {} \;

Warum nicht?

29voto

Commodore Jaeger Punkte 30016

Das Argument -exec von find führt den von Ihnen angegebenen Befehl einmal für jede gefundene Datei aus. Versuchen Sie es:

$ find . -type f -exec cat {} \; > out.txt

oder:

$ find . -type f | xargs cat > out.txt

xargs wandelt seine Standardeingabe in Befehlszeilenargumente für den von Ihnen angegebenen Befehl um. Wenn Sie sich Sorgen um eingebettete Leerzeichen in Dateinamen machen, versuchen Sie es:

$ find . -type f -print0 | xargs -0 cat > out.txt

5voto

Hmm... find scheint bei der Ausgabe von out.txt in das aktuelle Verzeichnis zu rekursieren

Versuchen Sie etwas wie

find . -type f -exec cat {} \; > ../out.txt

3voto

JoMo Punkte 436

Sie könnten etwa so vorgehen:

$ cat `find . -type f` > out.txt

2voto

Jay Punkte 40418

Wie wäre es, wenn Sie die Ausgabe von find einfach in eine Datei umleiten, denn Sie wollen ja nur alle Dateien in eine große Datei katalogisieren:

find . -type f -exec cat {} \; > /tmp/out.txt

1voto

dlamblin Punkte 42420

Vielleicht haben Sie aus den anderen Antworten gefolgert, dass die > Symbol wird von der Shell interpretiert, bevor find es als Argument erhält. Aber um Ihr "warum nicht" zu beantworten, schauen wir uns Ihren Befehl an, der lautet:

$ find . -type f -exec cat > out.txt {} \;

Sie geben also find diese Argumente: "." "-type" "f" "-exec" "cat" Sie geben dem Redirect diese Argumente: "out.txt" "{}" y ";" . Dies verwirrt find indem sie die -exec Argumente mit einem Semikolon zu versehen und den Dateinamen nicht als Argument zu verwenden ("{}"), verwirrt möglicherweise auch die Umleitung.

Wenn man sich die anderen Vorschläge anschaut, sollte man es wirklich vermeiden, die Ausgabe im gleichen Verzeichnis zu erstellen, in dem man auch sucht. Aber sie würden unter diesem Gesichtspunkt funktionieren. Und die -print0 | xargs -0 Kombination ist sehr nützlich. Was Sie schreiben wollten, war wahrscheinlich eher so:

$ find . -type f -exec cat \{} \; > /tmp/out.txt

Wenn Sie wirklich nur eine Ebene von Unterverzeichnissen und nur normale Dateien haben, können Sie etwas Dummes und Einfaches wie dies tun:

cat `ls -p|sed 's/\/$/\/*/'` > /tmp/out.txt

Das wird ls um alle Ihre Dateien und Verzeichnisse aufzulisten, indem Sie '/' zu den Verzeichnissen, während sed fügt eine '*' zu den Verzeichnissen. Die Shell wird dann diese Liste interpretieren und die Globs expandieren. Vorausgesetzt, es entstehen nicht zu viele Dateien, die die Shell nicht verarbeiten kann, werden diese alle als Argumente an cat übergeben, und die Ausgabe wird in out.txt geschrieben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X