19

Почему это не работает?

ls *.txt | xargs cat > all.txt

(Я хочу объединить содержимое всех текстовых файлов в один файл all.txt.) find с -exec также должен работать, но мне бы очень хотелось понять синтаксис xargs.

Спасибо

4 ответа4

25

ls *.txt | xargs cat >> all.txt

может работать немного лучше, так как он будет добавлять в all.txt вместо того, чтобы создавать его снова после каждого файла.

Кстати, cat *.txt >all.txt также будет работать. :-)

3

Если некоторые из ваших имен файлов содержат ', "или пробел xargs не удастся из-за проблемы с разделителем

В общем, никогда не запускайте xargs без -0, так как он вернется и укусит вас однажды.

Попробуйте вместо этого использовать GNU Parallel:

ls *.txt | parallel cat > tmp/all.txt

или если вы предпочитаете:

ls *.txt | parallel cat >> tmp/all.txt

Узнайте больше о GNU Parallel http://www.youtube.com/watch?v=OpaiGYxkSuQ

1

all.txt - это файл в том же каталоге, поэтому cat запутывается, когда хочет записать из того же файла в тот же файл.

С другой стороны:

ls *.txt | xargs cat > tmp/all.txt

Это будет читать из текстовых файлов в вашем текущем каталоге в all.txt в подкаталоге (не входит в *.txt).

0

Вы также можете столкнуться с ограничением длины командной строки. Одной из причин использования xargs является то, что он разбивает входные данные на безопасные блоки размером с командную строку. Итак, представьте ситуацию, в которой у вас есть сотни тысяч .txt файлов в каталоге. ls *.txt не удастся. Вам нужно будет сделать

ls | grep .txt$ |xargs cat > /some/other/path/all.txt

В этом случае .txt$ является регулярным выражением, совпадающим со всем, что заканчивается на .txt (так что это не совсем похоже на *.txt , так как если у вас есть файл с именем atxt , то *.txt не будет соответствовать ему, но регулярное выражение .)

Использование другого пути связано с тем, что, как указали другие ответы, для all.txt используется шаблон *.txt поэтому между входом и выходом может возникнуть конфликт.

Обратите внимание, что если у вас есть какие-либо файлы с ' в их именах (и это может быть причиной unmatched single quote ), вы можете захотеть сделать

ls | grep --null .txt$ | xargs -0 cat > /some/other/path/all.txt

Опция --null указывает grep использовать вывод, разделенный символом \0 (он же ноль) вместо новой строки по умолчанию, а опция -0 для `xargs говорит ему ожидать ввода в том же формате. Это будет работать, даже если у вас есть имена файлов с символами новой строки в них.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .