如何在awk中的模板中粘贴多个FILENAME

如何在awk中的模板中粘贴多个FILENAME

我有一个模板 A.tsv (字段分隔符=\t):

Name    data

还有几个文件,例如B.txt和C.txt。

我想打印文件名中的文件名(但在新文件中),如下所示:

Name    data
B
C

我已经这样做了:

template="A.tsv"
for bla in data/*.txt ; do
r="$(basename -s ".txt" $bla)"
( head -n 1 $template
awk -F'\t' -v OFS="\t" -v filename=$r '{print filename}' $bla ) > test_name.tsv  ;
done

但它给了我:

Name    data
C
C
C
C
C
C
C

你知道我的命令有什么问题吗?

谢谢

答案1

带有详细注释的脚本:

#!/bin/bash

#using the template variable is redundant, but
#I assume you want to use that lateron
template="A.tsv"
#write header from template and create file "output.txt"
#overwrites old version of "output.txt" if existing
head -n 1 ${template} > output.txt

#loop over files:
for bla in data/*.txt ; do
   #get basename without file suffix, add result to "output.txt" 
   basename -s ".txt" ${bla} >> output.txt
done

请注意,您应该更喜欢使用${variable}"$varaible",尤其是对于文件名,否则如果文件名称中包含例如空格,脚本将中断。


为什么awk- 方法失败了?

awk以每行为基础运行。你的代码有这样的:

awk -v variable=$r '{print variable}' ${file}

因此,当您有一个包含 10 行的文件时,上述命令将执行 10 次并产生 10 行变量。要awk在一次运行后停止,请使用exit或指定应执行命令的行:

#execute command only on line no. 1
awk 'NR == 1 { print $1 }' file
#execute command and quit awk
awk '{ print 1 ; exit }'

原来的脚本还有哪里失败了?

>>会将输出附加到文件中,并>覆盖它。在您的脚本中,您有一个包含以下内容的循环:

( head -n 1 $template
awk [...] $bla ) > test_name.tsv

发生的情况是,对于 中的每场比赛data/*txt,都会运行此命令,从而覆盖 的以前版本test_name.tsv,只留下最后一次运行的版本。请注意您如何在每次循环运行中重写标头。

相关内容