Как объединить файлы в подкаталоге с Unix find execute и cat в один файл?

Я могу сделать это:

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

и так:

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

но не этот:

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

почему бы и нет?

8 ответов


аргумент find-exec запускает команду, которую вы указываете один раз для каждого найденного файла. Попробуйте:

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

или:

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

xargs преобразует стандартный ввод в аргументы командной строки для указанной вами команды. Если вас беспокоят встроенные пробелы в именах файлов, попробуйте:

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

Мда... find кажется рекурсивным по мере вывода.txt в текущей директории

попробуйте что-то вроде

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

вы можете сделать что-то вроде этого :

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

Как насчет просто перенаправления вывода find в файл, так как все, что вы хотите сделать, это cat все файлы в один большой файл:

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

возможно, вы сделали вывод из других ответов, что > символ интерпретируется оболочкой, прежде чем find получает его как аргумент. Но чтобы ответить на ваше "почему нет", давайте посмотрим на вашу команду, которая:

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

так ты даешь find эти аргументы: "." "-type" "f" "-exec" "cat" вы даете перенаправить эти аргументы: "out.txt" "{}" и ";". Это смущает find не прерывает -exec аргументы с запятой и не используя имя файла в качестве аргумента ("{}"), возможно, это также путает перенаправление.

глядя на другие предложения, вы действительно должны избегать создания вывода в том же каталоге, который вы найдете. Но они будут работать, имея это в виду. И -print0 | xargs -0 комбинация очень полезна. Что вы хотели тип, наверное, был:

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

теперь, если у вас действительно есть только один уровень вложенных каталогов и только обычные файлы, вы можете сделать что-то глупое и простое, как это:

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

что получает ls чтобы перечислить все ваши файлы и каталоги, добавляя '/' в каталоги, в то время как sed добавляет '*' в каталогах. Затем оболочка интерпретирует этот список и развернет глобусы. Предполагая, что это не приведет к слишком большому количеству файлов для обработки оболочки, все они будут переданы в качестве аргументов cat, а вывод будет записан.формат txt.


или просто оставьте находку, которая бесполезна, если вы используете действительно большую оболочку Z (zsh), и вы можете сделать это:

setopt extendedglob

(это должно быть в вашей .zshrc) Затем:

cat **/*(.) > outfile 

просто работает :-)


попробуйте это:

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

в bash, вы могли бы сделать

cat $(find . -type f) > out.txt

С помощью $ () вы можете получить вывод из команды и передать его другому