Shell 提取列';x';从多个文件,并将文件名转换为';x';
我试图从多个txt文件(file1.txt、file2.txt、、、等)中提取列“m”,并将每列转换为新文件中的一行 下面是Shell 提取列';x';从多个文件,并将文件名转换为';x';,shell,unix,awk,find,cut,Shell,Unix,Awk,Find,Cut,我试图从多个txt文件(file1.txt、file2.txt、、、等)中提取列“m”,并将每列转换为新文件中的一行 下面是file1.txt: contig_1 contig_1 geneX ctg1_886;ctg1_887;ctg1_888 contig_2 contig_2 geneY ctg1_886;ctg1_887;ctg1_888 contig_3 contig_3 genesZ ctg1_886;ctg1_8
file1.txt
:
contig_1 contig_1 geneX ctg1_886;ctg1_887;ctg1_888
contig_2 contig_2 geneY ctg1_886;ctg1_887;ctg1_888
contig_3 contig_3 genesZ ctg1_886;ctg1_887;ctg1_888
我想要一个summary.txt
文件,它看起来像:
file1 geneX geneY geneZ
file2 geneA geneY
.
.
.
etc.
总行号可能因文件而异。我尝试使用
awk
,但没有成功。根据glenn jackmans的评论建议,GNU awk解决方案如下所示:
awk 'BEGIN {ORS=" "} BEGINFILE{print FILENAME} {print $3} ENDFILE{ printf("\n")}' file*.txt
awk解决方案可能是这样的(抱歉,只有gnu awk用于测试):
解释
有几种特殊模式:
,其操作在开始时执行一次。在这里,BEGIN
(输出记录分隔符)被设置为空格,其效果是从每个原始行获得一个新列,这是转置步骤ORS
操作在末尾执行一次END
和BEGINFILE
操作在处理每个文件的开始和结束时执行一次。在这里,ENDFILE
分别打印换行符文件名
for f in file*.txt ; do
echo $f `tr -s ' ' < $f | cut -d ' ' -f 3`
done > summary.txt
在awk中,当FNR为1时,使用自定义输出记录分隔符和规则将非常容易。file1.txt是file1.txt的第一行吗?我从这两篇文章中得到了启发不,file1.txt不是file1.txt的第一行。le colname仅在文件名中。请注意,BEGINFILE和ENDFILE需要GNU awk。这确实有效。请您快速注释代码的不同部分。此外,我的文件类似于file1-pattern.txt。上面的代码保留了整个名称,我可以直接在代码中grep部分文件1吗。否则,我可以事后再做。@user3037937我添加了解释。我不知道你需要什么文件名,但是你有完整的awk字符串处理函数,可以从
filename
中提取子字符串,并且只打印与file1
对应的子字符串@Lars Fisher,非常感谢你的澄清和提取提示。
for f in file*.txt ; do
echo $f `tr -s ' ' < $f | cut -d ' ' -f 3`
done > summary.txt
for f in file*.txt ; do
echo $f `cut -f 3 $f`
done > summary.txt