Как объединить файлы в подкаталоге с 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
Как насчет просто перенаправления вывода 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
просто работает :-)
в bash, вы могли бы сделать
cat $(find . -type f) > out.txt
С помощью $ () вы можете получить вывод из команды и передать его другому