【问题标题】:My loop is outputting to one concatenated file instead of several individual files我的循环输出到一个连接文件而不是几个单独的文件
【发布时间】:2021-02-01 16:35:49
【问题描述】:

我有一堆 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

生成的文件在哪里写入了所有输出,但是我怎样才能让每次迭代都生成一个唯一的文件名? 谢谢。

【问题讨论】:

    标签: linux loops find filenames cut


    【解决方案1】:

    如果我理解正确,我会这样做。同意之前关于 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
    

    【讨论】:

      【解决方案2】:

      根据您的示例,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",$1,$7 >> FILENAME".F" }' '{}' +
      

      【讨论】:

      • 这遇到了我使用cut时遇到的同样问题。而不是给我两个文件 - 原始文件,然后是一个带有 .F 后缀的第 1,7 列的文件,它只是给了我每个文件中的所有信息,并连接到一个名为 ``` {}.F ``` 的文件中.以这种方式使用 find 可能有问题?
      • 在我的本地 bash 环境中测试时效果很好。您使用的是什么外壳/环境?
      • 我正在使用 BASH
      • 尝试替代解决方案
      猜你喜欢
      • 1970-01-01
      • 2016-10-02
      • 2017-12-19
      • 1970-01-01
      • 2021-11-27
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      相关资源
      最近更新 更多