在bash中将循环的每次迭代的输出附加到相同的内容
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在bash中将循环的每次迭代的输出附加到相同的内容相关的知识,希望对你有一定的参考价值。
我有44个文件(每个染色体2个)分为两种类型:.vcf和.filtered.vcf。我想在循环中为每个人制作一个wc -l
,并将输出始终附加到同一个文件中。但是,我想在这个文件中有3列:chr [1-22],.vcf的wc -l
和.filtered.vcf的wc -l
。
我一直在尝试为每个文件做独立的wc -l
并将每个染色体的2个输出按列粘贴在一起,但这显然效率不高,因为我生成了大量不必要的文件。我正在为22对文件尝试此代码:
wc -l file1.vcf | cut -f 1 > out1.vcf
wc -l file1.filtered.vcf | cut -f 1 > out1.filtered.vcf
paste -d " " out1.vcf out1.filtered.vcf
我想只有一个包含三列的输出文件:
Chromosome VCFCount FilteredVCFCount
chr1 out1 out1.filtered
chr2 out2 out2.filtered
任何帮助将不胜感激,非常感谢您提前:)
printf "%s
" *.filtered.vcf |
cut -d. -f1 |
sort |
xargs -n1 sh -c 'printf "%s %s %s
" "$1" "$(wc -l <"${1}.vcf")" "$(wc -l <"${1}.filtered.vcf")"' --
- 输出新行分隔的目录中的文件列表
- 删除带切口的扩展(可能是
xargs -i basename {} .filtered.vcf
上的东西会更安全) - 对它进行排序(对于很好的排序输出!)(可能在
sort -tr -k2 -n
上的东西会按数字排序,甚至会更好)。 xargs -n1
对于每个文件执行脚本sh -c
printf "%s %s %s "
- 使用自定义格式字符串输出..."$1"
- 文件名和..."(wc -l <"${1}.vcf")"
- 计算.vcf文件中的行和..."$(wc -l <"${1}.filtered.vcf")"
- .filtered.vcf中的行数
例:
> touch chr{1..3}{,.filtered}.vcf
> echo > chr1.filtered.vcf ; echo > chr2.vcf ;
> printf "%s
" *.filtered.vcf |
> cut -d. -f1 |
> sort |
> xargs -n1 sh -c 'printf "%s %s %s
" "$1" "$(wc -l <"${1}.filtered.vcf")" "$(wc -l <"${1}.vcf")"' --
chr1 0 1
chr2 1 0
chr3 0 0
要使用标题看起来漂亮的表,请使用column
:
> .... | column -N Chromosome,VCFCount,FilteredVCFCount -t -o ' '
Chromosome VCFCount FilteredVCFCount
chr1 0 1
chr2 1 0
chr3 0 0
也许试试这个。
for chr in chr*.vcf; do
base=${chr%.vcf}
awk -v base="$base" 'BEGIN { OFS=" "
# Remove this to not have this pesky header line
print "Chromosome", "VCFCount", "FilteredVCFCount"
}
FNR==1 && n { p=n }
{ n=FNR }
END { print base, p, n }' "$chr" "$base.filtered.vcf"
done >counts.txt
非常简单的Awk脚本只收集每个文件的最高行号(所以我们基本上重新实现wc -l
)并以所需的格式打印收集的数字。 FNR
是当前输入文件中的行号;我们只是保存它,并将值复制到p
,以便在切换到新文件时从单个变量中保存前一个文件中保存的值(从第1行开始)。
shell参数替换${variable%pattern}
检索variable
的值,并删除pattern
上的任何后缀匹配。 (还有${variable#pattern}
删除前缀,Bash有##
和%%
来修剪最长的模式匹配而不是最短的。)
如果效率很重要,你可以将所有脚本重构为一个Awk脚本,但这样,所有部分都很简单,希望可以理解。
以上是关于在bash中将循环的每次迭代的输出附加到相同的内容的主要内容,如果未能解决你的问题,请参考以下文章
sh 如何在shell脚本/ bash中将输出附加到文本文件的末尾?