【问题标题】:Concatenate awk-output, string, and text file连接 awk 输出、字符串和文本文件
【发布时间】:2019-04-03 11:49:49
【问题描述】:

我的当前目录中有以下两个制表符分隔的文件。

a.tsv

do  not use this    line
but this    one
and that    too

b.tsv

three   fields  here
not here

对于每个tsv文件,在同一目录下都有一个关联的txt文件,文件名相同,后缀不同。

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

我很想知道为什么倒数第二个代码不能按预期工作,以及完成这项任务的好的解决方案是什么。

【问题讨论】:

  • 很高兴您已经付出了努力,如果您可以在您的帖子中使用代码标签发布输入和预期输出示例,这将非常有助于我们理解完整的问题。
  • 我尝试相应地编辑问题。

标签: bash awk


【解决方案1】:

也许你想重定向一系列命令

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

请注意,左大括号后的空格和右大括号前的分号或换行符很重要。

您似乎也混淆了命令替换$() 和进程替换&lt;()&gt;()。另外&lt;&lt;&lt; 是将内容重定向为标准输入,而&lt; 用于重定向文件。

【讨论】:

  • 这正是我想要的,就这么简单。我不知道可以像这样重定向一系列命令。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
相关资源
最近更新 更多