Как объединить файлы в подкаталоге с Unix find execute и cat в один файл? - PullRequest
9 голосов
/ 03 октября 2008

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

$ 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 ]

28 голосов
/ 03 октября 2008

Аргумент 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
5 голосов
/ 04 октября 2008

Хмм ... похоже, что поиск повторяется при выводе out.txt в текущий каталог

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

find . -type f -exec cat {} \; > ../out.txt
3 голосов
/ 03 октября 2008

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

$ cat `find . -type f` > out.txt
2 голосов
/ 03 октября 2008

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

find . -type f -exec cat {} \; > /tmp/out.txt
1 голос
/ 04 октября 2008

Возможно, из других ответов вы пришли к выводу, что символ > интерпретируется оболочкой, прежде чем 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, а выходные данные будут записаны в out.txt.

0 голосов
/ 04 октября 2008

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

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

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

0 голосов
/ 04 октября 2008

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

(find . -type f -exec cat {} \;) > out.txt 
0 голосов
/ 03 октября 2008

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

setopt extendedglob

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

cat **/*(.) > outfile 

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...