Объединение текстовых файлов и добавление сепаратора

Прочтите руководство по rsync . Rsync - ваш друг, когда вы хотите сохранить атрибуты.

По сути, чего-то вроде rsync -lHAXogtE должно быть (более чем) достаточно, если я правильно вас понимаю.

1
08.10.2018, 00:27
4 ответа

Я бы упростил ваши команды следующим образом:

  #!/bin/bash
  for file in *.txt; do
  cat $file >> Combined.txt
  printf '\n\n=========\n\n' >> Combined.txt
  done
0
27.01.2020, 23:42

Если вы собираетесь делать это с тысячами файлов, вы можете не запускать несколько команд для каждого файла. С ГНУawk:

printf '%s\0'./*.txt | xargs -r0 gawk '
  BEGINFILE {if (NR) print "\n==========\n"};1' > combined.out

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

Или используйте оболочку, в которой catвстроен, напримерksh93:

#! /bin/ksh93
firstpass=true
for file in *.txt; do
  "$firstpass" || print '\n===========\n'
  firstpass=false
  command /opt/ast/bin/cat < "$file"
done > combined.out

Все эти команды в цикле встроены -, поэтому их выполнение не требует создания новых процессов или загрузки внешнего исполняемого файла, что делает производительность приемлемой.

1
27.01.2020, 23:42

Использование FNRи NRвawk

#!/bin/bash

outfile="$( mktemp combined.txt.XXXXXX )"

echo "Output file: ${outfile}"

awk 'FNR==1 && NR>1 { printf("\n%s\n\n","========") } 1' *.txt > "${outfile}"

echo "Finished."

Строка -по -описание строки:

outfile="$( mktemp combined.txt.XXXXXX )"

Используйте mktempдля создания нового пустого файла с уникальным именем (, например,combined.txt.HDpgMn). Вы можете использовать больше Xсимволов для более длинного случайного суффикса. Включите команду в "$(... )", чтобы сохранить имя нового файла в переменной outfile.

echo "Saving to file: ${outfile}"

Печать имени выходного файла. (Когда сценарий завершится, вы можете переименовать выходной файл, чтобы удалить строку случайных символов, следующую за .txt.)

awk 'FNR==1 && NR>1 { printf("\n%s\n\n","========") } 1' *.txt > "${outfile}"

Распечатать...

  • пустая строка,
  • короткая строка из символов "=",
  • и еще одна пустая строка

...в начале каждого входного файла, кроме первого входного файла. FNRподсчитывает количество строк входного файла, сбрасывая значение в начале каждого файла. NRподсчитывает номера строк и не сбрасывает.

В операторе awk1непосредственно перед закрывающей одинарной кавычкой оценивается как TRUEдля каждой строки и выполняет действие по умолчанию для печати этой строки. (Другими словами, awk '1'работает как cat.)

echo "Finished."

Сообщить пользователю, когда скрипт завершится. (Не обязательно, так как вы все равно увидите командную строку, но это не помешает.)

0
27.01.2020, 23:42

Почему бы просто не

printf "\n\n=====\n\n" > XTMP
cat $(printf "%s XTMP " *.txt) > combined.tmp

Поместите разделитель во временный файл и используйте функцию printfдля повторения строки форматирования для каждого найденного аргумента, поэтому команда catбудет выглядеть как

cat 1.txt XTMP 2.txt XTMP... n.txt XTMP

Вы можете столкнуться с системными ограничениями (, например. LINE _MAX ), хотя...

0
27.01.2020, 23:42

Теги

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