我想根据键值向文件添加一列。 我有 infile_chr"N".txt (其中 N 是从 1 到 22 的数字),并且我需要一个输出文件 (outfile.txt),其中第一列是 N。
这里有一个输出文件的示例:
1 856108 0.02625
1 870806 0.02625
1 884635 0.02625
...
22 51111340 0.02625
22 51135384 0.02625
但是在输入文件中没有数字为N的列。这里输入文件“infile_chr1.txt”的前两行,标有**的地方可以找到我要打印的列:
**856108** 14774 908823 40 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, () 0.025 0.024375 **0.02625** 0.975 0.02875
**870806** 55545 921716 40 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, () 0.025 0.024375 **0.02625** 0.975 0.02875
我尝试使用以下代码:
for K in {1..22}; do awk '{$2="$K"; print $2,$1,$9}' infile_chr"$K".txt >> outfile.txt; done
但输出错误:
$K 856108 0.02625
$K 870806 0.02625
$K 884635 0.02625
$K 899937 0.02625
$K 908823 0.02625
有人可以帮助我吗? 非常感谢。
您不需要进行 bash 循环。
awk
可以通过一个命令来完成此操作,如下所示:
awk 'FNR == 1 {f = FILENAME; gsub(/^infile_chr|\.txt$/, "", f)}
{print f, $1, $9}' infile_chr* > output
cat output
1 856108 0.02625
1 870806 0.02625
...
...
22 356102 0.08719
22 670808 0.05442
awk '{$2="$K"; print $2,$1,$9}'
这不是在GNU
AWK
中使用shell变量的正确方法,如果你想访问这样的变量,你应该使用--assign var=val
或-v var=val
。在这种特殊情况下,修复代码将导致
for K in {1..22}; do awk --assign K="$K" '{$2=K; print $2,$1,$9}' infile_chr"$K".txt >> outfile.txt; done
但您不需要 shell
for
装置,因为您可以向 GNU AWK
的 ARGV 提供要使用的文件名。例如,如果我需要将第一列从 TAB 剪切的 file1.tsv
输出到 file10.tsv
,我可以通过 来做到这一点
awk 'BEGIN{for(i=1;i<=10;i+=1){ARGV[++ARGC]="file" i ".tsv"}}{print $1}'
说明:我在 AWK 中使用
for
循环,每次都会增加参数数量 (ARGC),并将从 file
数字 .tsv
创建的名称放在 ARGV 数组的所需位置。
(在 GNU Awk 5.1.0 中测试)