【问题标题】:Awk print file name within for loopawk在for循环中打印文件名
【发布时间】:2020-05-01 16:58:10
【问题描述】:

我正在对目录中的多个文件运行 for 循环。 for 循环中的每个命令都会在前一个 .txt 文件中附加一个新列。目前,for 循环中的第 3 行创建了一个带有文件路径的列,但我只需要文件名 - 我也不需要文件扩展名。我玩过拆分和管道回到 awk,但没有运气。

在调整 awk 命令以仅获取文件名后,我想制作一个包含所有循环值的主 .txt 文件。本质上,我认为我需要在每个循环的输出中附加一个 .txt 文件。现在这就是我正在尝试对 for 循环第三行中的管道执行的操作,但它只是创建了一个空的 .txt 文件。

for file in ~/Desktop/test/*bam
do
    bedtools multicov -bams "$file" -bed bed_for_multicov.bed >  "${file%%_RRemoved.bam}_counts.txt"
    awk '{print $0,a}' a="$(samtools view -c "$file")" ${file%%_RRemoved.bam}_counts.txt > ${file%%_RRemoved.bam}_CPMcounts.txt
    awk -v var="$file" '{print $0, var}' ${file%%_RRemoved.bam}_CPMcounts.txt > ${file%%_RRemoved.bam}_CPMcounts2.txt | >> CPMcountsMaster.txt
done

当前文件名1_CPMcounts2.txt 输出

chr1    11088   11488   peak_1  192 4409922 path/to/filename1.bam
chr1    20674   21215   peak_2  217 4409922 path/to/filename1.bam
chr1    28550   28862   peak_3  170 4409922 path/to/filename1.bam
chr1    29582   30300   peak_4  437 4409922 path/to/filename1.bam
chr1    30635   31720   peak_5  696 4409922 path/to/filename1.bam
chr1    32373   35541   peak_6  2877 4409922 path/to/filename1.bam

当前文件名2_CPMcounts2.txt 输出

chr1    11088   11488   peak_1  293 5888360 path/to/filename2.bam
chr1    20674   21215   peak_2  439 5888360 path/to/filename2.bam
chr1    28550   28862   peak_3  392 5888360 path/to/filename2.bam
chr1    29582   30300   peak_4  901 5888360 path/to/filename2.bam

所需的文件名1_CPMCounts2.txt 输出

chr1    11088   11488   peak_1  192 4409922 filename1
chr1    20674   21215   peak_2  217 4409922 filename1
chr1    28550   28862   peak_3  170 4409922 filename1
chr1    29582   30300   peak_4  437 4409922 filename1
chr1    30635   31720   peak_5  696 4409922 filename1
chr1    32373   35541   peak_6  2877 4409922 filename1

所需的最终 CPMcountsMaster.txt

chr1    11088   11488   peak_1  192 4409922 filename1
chr1    20674   21215   peak_2  217 4409922 filename1
chr1    28550   28862   peak_3  170 4409922 filename1
chr1    29582   30300   peak_4  437 4409922 filename1
chr1    30635   31720   peak_5  696 4409922 filename1
chr1    32373   35541   peak_6  2877 4409922 filename1
chr1    11088   11488   peak_1  293 5888360 filename2
chr1    20674   21215   peak_2  439 5888360 filename2
chr1    28550   28862   peak_3  392 5888360 filename2
chr1    29582   30300   peak_4  901 5888360 filename2

【问题讨论】:

  • 变量是FILENAME。另见 POSIX awkFILENAME 也是一个标准的内置变量,因此它可能在大多数版本的awk 中都可用。
  • 为什么Desired Final CPMcountsMaster.txt 的行数比Current filename2_CPMcounts2.txt output 多?只需通过basename the_file .bam 管道传输最后一列。你确定你提交的脚本有效吗?
  • 如果您希望基本名称作为“文件名”输出,请将a="$(samtools view -c "$file")" 替换为a=$(basename $(samtools view -c "$file") .bam)"。请注意,现代 $(…) 表示法的优点之一是嵌套调用比使用旧的反引号表示法进行命令替换要容易得多。
  • 文件名来自第 3 行,而不是包含 samtools 的行。我之前尝试过 FILENAME,但它在我的 for 循环中不起作用 - 它调用了 .txt 文件的名称(不是循环中的 $file)。
  • 作为一般性评论,我对您获得的输出和变量替换的使用有点困惑。例如。您使用 ${file%%_RRmoved.bam} 似乎暗示存储在 $file 中的文件名以字符串 RRemoved.bam 结尾。您最后一次 awk 传递了相同的变量,但在输出中我们看不到这个字符串。你也有命令 | >> 输出文件。这是无效的语法。始终尝试先使用shellcheck.net 解析您的代码。它可以挽救生命!

标签: for-loop awk filenames


【解决方案1】:

以下作品,改编自 J Leffler 的评论 - 谢谢!

for file in ~/Desktop/test/*bam
do
    bedtools multicov -bams "$file" -bed bed_for_multicov.bed >  "${file%%_RRemoved.bam}_counts.txt"
    awk '{print $0,a}' a="$(basename "$file" _RRemoved.bam)" ${file%%_RRemoved.bam}_CPMcounts.txt > ${file%%_RRemoved.bam}_CPMcounts2.txt
    awk '{print $0,a}' a="$(basename "$file" _RRemoved.bam)" ${file%%_RRemoved.bam}_CPMcounts.txt >> CPMcountsMaster.txt
done

【讨论】:

  • 这是怎么回事,这甚至和你原来的脚本不一样?
猜你喜欢
  • 2020-04-21
  • 1970-01-01
  • 2018-04-15
  • 1970-01-01
  • 2016-12-23
  • 2020-09-08
  • 1970-01-01
  • 2021-09-19
  • 2018-06-01
相关资源
最近更新 更多