问题描述
我有一堆 tsv 文件,每个文件有 7 列,但我只对第 1 列和第 7 列感兴趣。每个文件的格式为:SampleName.bam.S.txt。
Example: 7805.bam.S.txt 7806.bam.S.txt 7808.bam.S.txt etc...
我尝试了两件事:
1) find . -type f -name '*.S.txt' -exec cut -f 1,7 {} > {}.F \; and
2) for f in '*.S.txt';do cut -f 1,7 "$f" > "$f".F;done
我想要的是我现在的目录
7805.bam.S.txt 7805.bam.S.txt.F 7806.bam.S.txt 7806.bam.S.txt.F 7808.bam.S.txt 7808.bam.S.txt.F etc...
但我只是得到
1) 7805.bam.S.txt 7806.bam.S.txt 7808.bam.S.txt etc... {}.F
2) 7805.bam.S.txt 7806.bam.S.txt 7808.bam.S.txt etc... $f.F
生成的文件将所有输出写入其中,但如何让每次迭代生成唯一的文件名? 谢谢。
解决方法
根据您的示例,awk 可能是更好的候选者
find . -maxdepth 1 -name "*.S.txt" -exec awk -F "\t" '{ printf "%s\t%s\n",$1,$7 }' '{}' > '{}'.F \;
查找所有以 .S.txt 结尾的文件,然后使用找到的文件执行 awk 语句,该语句将制表符设置为字段分隔符,然后仅打印由制表符分隔的第 1 个和第 7 个字段。我们将输出重定向到另一个具有相同名称但末尾带有“.F”的文件。
或者,您可以直接打印到 awk 本身中的文件。然后,您可以使用 find (+) 中的文件组并提高效率:
find . -maxdepth 1 -name "*.S.txt" -exec awk -F "\t" '{ printf "%s\t%s\n",$7 >> FILENAME".F" }' '{}' +
,
如果我理解正确的话,我会这样做。同意之前关于 awk 处理 tsv/csv 的答案——这绝对是正确的工具。我只是发现用于迭代和变量的 bash 语法比 awk 语法更容易记住。
find . -type f -name "*.S.txt" | while read FILE;do awk -F"\t" '{print $1"\t"$7}' $FILE > $FILE.F;done