Почему это не работает? «ls * .txt | xargs cat> all.txt» (все файлы в одном текстовом документе)

29649
ajo

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

ls *.txt | xargs cat > all.txt 

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

Спасибо

18

4 ответа на вопрос

25
Janne Pikkarainen

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

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

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

Кошка * .txt> all.txt естественно лучше. Спасибо ajo 13 лет назад 5
Тем не менее, ... | xargs cat >> all.txt или> all.txt всегда возвращают ошибку с xargs: непревзойденная одинарная кавычка ... Это потому, что xargs принимает все после него как команду? ajo 13 лет назад 0
У вас есть имена файлов с пробелами? Если это так, используйте вместо этого что-то вроде «find / your / path -iname '* .txt' -print0 | xargs -0 cat >> all.txt». Janne Pikkarainen 13 лет назад 1
нет, я заменил все пробелы в именах файлов на _. Но если подумать, некоторые имена файлов могут включать одинарные кавычки, как в листинге_O'Connor_.txt, это может быть проблемой! ajo 13 лет назад 1
Да, это проблема тогда. :) Самый простой и разумный способ - использовать поиск с -print0 в сочетании с xargs -0 - тогда вся цепочка будет использовать символ NULL в качестве разделителя, а пробел и специальные символы будут обрабатываться автоматически. Janne Pikkarainen 13 лет назад 0
Действительно: после удаления одинарных кавычек в некоторых именах файлов через «s / '/ _ / g» * .txt, команда работает нормально !! Но можно ли это сделать изнутри xargs через какую-то опцию ??? ajo 13 лет назад 0
Хорошо, найти тоже неплохо ... Я помню, что у меня были похожие проблемы, когда имена файлов содержали пробелы !! ajo 13 лет назад 0
find намного лучше, чем ls, если вам нужно перейти в подкаталоги. Janne Pikkarainen 13 лет назад 0
для последнего: как насчет ls -R? (кроме строки каталога ?!) ajo 13 лет назад 0
ls -R может подойти для удобочитаемой формы, но если вам нужно что-то обрабатывать с помощью xargs или других инструментов - не так много. Видите, ls -R не перечисляет полный путь вместе с каждым именем файла, но команда find или tree сделает это. Делает скрипты намного проще. При написании сценариев или прокачке, пожалуйста, избавьтесь от ls и используйте более продвинутые инструменты :-) Janne Pikkarainen 13 лет назад 0
Это потенциально очень опасная команда. Если «all.txt» уже существует, выполнение этой команды расширится, чтобы заполнить все доступное пространство на жестком диске. Dan Loewenherz 9 лет назад 0
3
Ole Tange

Если некоторые из ваших имен файлов содержат ', "или пробел не 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
Jeremy Smyth

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

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

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

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

Еще следующая ошибка: xargs: непревзойденная одинарная кавычка; по умолчанию кавычки являются специальными для xargs, если вы не используете опцию -0 ajo 13 лет назад 0
У вас есть файл .txt с одинарной кавычкой в ​​названии? Jeremy Smyth 13 лет назад 1
0
Brian Minton

You could also come across a command line length limitation. Part of the reason for using xargs is that it splits up the input into safe command-line-sized chunks. So, imagine a situation in which you have hundreds of thousands of .txt files in the directory. ls *.txt will fail. You would need to do

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

.txt$ in this case is a regular expression matching everything that ends in .txt (so it's not exactly like *.txt, since if you have a file called atxt, then *.txt would not match it, but the regular expression would.)

The use of another path is because, as other answers have pointed out, all.txt is matched by the pattern *.txt so there would be a conflict between input and output.

Note that if you have any files with ' in their names (and this may be the cause of the unmatched single quote error), you would want to do

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

The --null option tells grep to use output separated by a \0 (aka null) character instead of the default newline, and the -0 option to `xargs tells it to expect its input in the same format. This would work even if you had file names with newlines in them.

Похожие вопросы