Как объединить 12000 файлов в 4 файла на основе первой строки?

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

Если вам нужно возвращаемое значение команды оболочки, оно сохраняется вresult.rc:

- name: Install JDK8
  shell: cd /tmp/install/ && tar -zxvf jdk-8u51-linux-x64.tar.gz
  register: result
  ignore_errors: true
- debug:
    msg: "The return value was: {{ result.rc }}"

shellзадачи плохи для идемпотентности, вы можете попробовать использовать, например. модуль package.

0
28.06.2021, 23:24
2 ответа

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

IFS=$'\n' i=1; for header in $(egrep -m1 '> [0-9]' * -oh | sort | uniq); do grep -rl "$header". | xargs -I{} cat {} >> file${i}; ((i++)); done

Запустите эту команду в каталоге, содержащем файл 12000, после чего у вас будут отдельные файлы с именами файл1, файл2, файл3 и т. д., каждый из которых содержит все файлы с одинаковым началом заголовка ("> 1", " > 2" )соединяются вместе.

Пояснение:

egrep -m1 '> [0-9]' * -oh | sort | uniq - find all headers starting with "> number" ("> 1", "> 2") and remove duplicates.

IFS=$'\n' i=1; for header in $(...); do...; done - iterate over the list of headers.

grep -rl "$header". | xargs -I{} cat {} >> file${i}; ((i++)); - for each header concat all files started by the header to a separate file.
1
28.07.2021, 11:21
awk 'FNR==1 && ! /^> 4/ {nextfile}1' * > speciesX.txt

Это приведет к переходу к следующему файлу, если первая строка текущего файла не начинается с > 4. Все остальные строки выводятся на стандартный вывод. stdout перенаправляется оболочкой на speciesX.txt.

Обратите внимание, :1в конце скрипта оценивается как истина , что приводит к выполнению действия awk по умолчанию (печати текущей строки ). Это распространенная awkидиома, потому что awk-скрипты, по сути, представляют собой ряд test-condition { action-if-true }правил, в которых либо условие проверки, либо действие могут быть опущены. Если тестового условия нет, действие выполняется всегда, а если нет, по умолчанию используется print.


Достаточно просто изменить один из вышеперечисленных вкладышей -, чтобы он соответствовал /^> 1/, /^> 2/и т. д., и перенаправить на разные файлы при каждом запуске, но если вы хотите создать выходные файлы для всех входных файлов на однажды, всего одним запуском скрипта, вы могли бы сделать что-то вроде этого:

awk 'FILENAME ~ /\.out$/ {nextfile};
     FNR==1 && ! /^> [0-9]/ {nextfile};
     FNR==1 {outfile=$2 ".out"};
     {print > outfile}' *.txt

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

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

В противном случае «.out» добавляется ко второму полю первой строки для построения имени выходного файла.

Каждая строка ввода затем печатается в выходное имя файла. В итоге вы получите файлы 1.out, 2.out, 3.out, 4.outи т. д.Вы можете переименовать их позже с помощью mv.

Обратите внимание, что перенаправление >и >>работает немного иначе в awk, чем в оболочке:

  • Shell будет стирать и перезаписывать существующий файл каждый раз, когда используется >(вы должны использовать >>для добавления в файл ).
  • Awk будет стирать и перезаписывать файл только в первый раз он увидит это имя файла в рамках одного запуска скрипта , весь последующий вывод в файл с тем же именем (] в том же запуске скрипта добавляется ). >>предотвращает стирание и перезапись даже в первый раз, когда скрипт видит имя файла, т. е. оно всегда будет добавляться.

Кстати, последняя строка скрипта {print > outfile}является примером правила awk, в котором есть действие без тестового -условия. Это выполняется для каждой входной строки (, если предыдущее действие правила не было чем-то вроде nextили nextfileдля немедленного перехода к следующей строке или следующему файлу ).

2
28.07.2021, 11:21

Теги

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