Объединить awk-вывод, строку и текстовый файл - PullRequest
0 голосов
/ 03 апреля 2019

В моем текущем каталоге есть следующие два файла, разделенных табуляцией.

a.tsv

do  not use this    line
but this    one
and that    too

b.tsv

three   fields  here
not here

Для каждого файла tsv есть связанный текстовый файл в том же каталоге, с тем же именем файла, но с другим суффиксом.

a.txt

This is the a-specific text.

b.txt

Text associated to b.

Для каждой пары файлов я хочу создать новый файл с тем же именем, но с суффиксом _new.txt. Новые файлы должны содержать все строки из соответствующего файла tsv, которые содержат ровно 3 поля, затем строку \n####\n, а затем все содержимое соответствующего файла txt. Таким образом, должны быть созданы следующие выходные файлы.

Желаемый вывод

a_new.txt

but this    one
and that    too

####
This is the a-specific text.

b_new.txt

three   fields  here

####
Text associated to b.

Работающее, но плохое решение

for file in ./*.tsv
do awk -F'\t' 'NF==3' $file > ${file//.tsv/_3_fields.tsv}
done

for file in ./*_3_fields.tsv
do cat $file <(printf "\n####\n") ${file//_3_fields.tsv/.txt} > ${file//_3_fields.tsv/_new.txt}
done

нерабочий код

Я бы хотел получить результат одним скриптом и не создавать промежуточный файл с суффиксом _3_fields.tsv. Я попробовал подстановку команд следующим образом:

for file in ./*.tsv
do cat <<< $(awk -F'\t' 'NF==3' $file) <(printf "\n####\n") ${file//.tsv/.txt} > ${file//.tsv/_new.txt}
done

Но это не записывает обработанную awk часть в новые файлы.

Тем не менее, подстановка команд, похоже, сработает, если я только запишу обработанную awk часть в новый файл следующим образом:

for file in ./*.tsv; do cat <<< $(awk -F'\t' 'NF==3' $file) > ${file//.tsv/_new.txt}; done

Мне было бы интересно узнать, почему второй последний код не работает должным образом, и каким хорошим решением было бы решение этой задачи.

1 Ответ

5 голосов
/ 03 апреля 2019

Возможно, вы хотите перенаправить последовательность команд

for file in ./*.tsv
do 
    {
        awk -F'\t' 'NF==3' "$file"
        printf "\n####\n"
        cat "${file//.tsv/.txt}"
    } > "${file//.tsv/_new.txt}"
done

Обратите внимание, что пробел после открывающей скобки и точки с запятой или новой строки перед закрывающей скобкой важны.

Кажется, вы также путаете подстановку команд$() и процесс замены <() или >().Также <<< предназначен для перенаправления содержимого в качестве стандартного ввода, тогда как < для перенаправления файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...