Объединение тысяч файлов:> vs >>

Я нашел два, казалось бы, противоречивых ответа на StackOverflow на следующие вопросы:

  • Конкатенация тысяч текстовых файлов через сотни каталогов (при сохранении некоторой структуры)
  • Как объединить файлы в подкаталоге с Unix find execute и cat в один файл?

Верхний ответ на первый вопрос предполагает:

find . -name *.txt -print0 | xargs -0 cat >> out.txt

в то время как верхний ответ на второй вопрос предполагает:

find . -name *.txt -print0 | xargs -0 cat > out.txt

Насколько я знаю, первый из них правильный, поскольку он использует оператор >> (append), но не второй, так как он использует оператор > который, как я думал, просто перенаправляет вывод в файл. Однако второй ответ имеет больше голосов (10) и также был принят без комментариев. Правильно ли отвечают оба ответа? Зачем? Какова цель этих двух операторов?

Второй пример:

 find . -name '*.txt' -print0 | xargs -0 cat > out.txt 

Является полностью законным и будет воссоздавать файл, out.txt каждый раз, когда он запущен, а первый будет конкатенацией out.txt если он выполняется. Но обе команды делают практически одно и то же.

Проблема в том, что xargs -0 cat . Люди думают, что перенаправление на out.txt является частью этой команды, когда это не так. Переадресация происходит после того, как xargs -o cat принял вход через STDIN, а затем cat'ing, который выводит как отдельный поток в STDOUT. xargs оптимизирует cat'ing файлов, а не их выход.

Вот пример, который показывает, что я говорю. Если мы xargs -0 cat pv -l между xargs -0 cat и выходом в файл out.txt мы увидим, сколько строк написано cat.

пример

Чтобы показать это, я создал каталог с 10 000 файлов.

 for i in `seq -w 1 10000`;do echo "contents of file$i.txt" > file$i.txt;done 

Каждый файл выглядит примерно так:

 $ more file00001.txt contents of file00001.txt 

Выходной сигнал от pv :

 $ find . -name '*.txt' -print0 | xargs -0 cat | pv -l > singlefile.rpt 10k 0:00:00 [31.1k/s] [ <=> 

Как мы видим, строки 10k были записаны в файл singlefile.rpt . Если xargs передавали нам куски вывода, то мы увидели бы это путем уменьшения числа строк, которые были представлены pv .

Какова цель этих двух операторов?

Это просто: потому что есть разные варианты использования. Иногда полезно сначала усекать целевой файл на размер 0, иногда (например, файлы журналов), имеет смысл добавить данные в файл.

В этом случае нет смысла добавлять. Вам нужен файл с точно содержимым выбранных вами файлов, а не «файл с любыми данными в начале и содержимое выбранных файлов в конце».

Я бы пошел со вторым. Редирект stdout попадает в bash, когда вы нажимаете enter, поэтому не похоже, что вы создаете новый редирект для каждой строки find / xargs (что могло быть их мышлением). Если out.txt не существует, они должны быть одинаковыми, если у него уже есть данные, а затем второй, по меньшей мере, сбрасывает файл на известный контент (то есть без содержимого).