我有几个文件 (*data.txt),我试图根据第 1 列的内容将每个文件拆分为多个文件。我已设法将它们拆分,但我不知道如何使用 和 命名输出$filename
文件第 1 列($1) 使用print
.目前,以下命令中的打印给了我$1 ".txt"
,例如:ENSG00000108094.txt,ENSG00000115232.txt而不是file1_ENSG00000108094.txt,file1_ENSG00000115232.txt,这是不合适的,因为我需要为每个输入文件提供单独的输出。这是我的命令,我不确定应该在哪里使用"$b"
才能获得预期的结果。
for filename in *_data.txt
do
b=${filename%%_data.txt}
cat $filename | awk 'NR==1 {header = $0; next}!header_printed[$1]++ {print header > $1".txt"}{print > $1".txt"}'
done
谢谢。
答案1
有多种方法可以将 shell 变量传递到 awk 程序中:
使用
-v
命令行选项:awk -v b=${filename%data.txt} '... {print > (b $1 ".txt")}'
在 awk 程序之后将值作为普通参数传递
awk '... {print > (b $1 ".txt")}' b=${filename%data.txt}
传递值在环境并通过内部
ENVIRON
数组在 awk 中访问它b=${filename%data.txt} awk '... {print > (ENVIRON["b"] $1 ".txt")}'
但是,如果您只有“几个”文件,则完全省略 shell 循环并将所有通配文件直接传递给 awk 可能是有意义的,您可以在其中从FILENAME
内部变量导出输出文件前缀,例如:
awk '
FNR==1 {header = $0; b = FILENAME; sub(/data.txt$/,"",b); next}
!header_printed[b $1]++ {print header > (b $1 ".txt")}
{print > (b $1 ".txt")}
' *_data.txt
(您也可以使用split
orsubstr
删除data.txt
后缀 - 我使用正则表达式,sub
因为它最接近${filename%data.txt}
shell 扩展)。