awk 在与键值对应的列中打印一个值

问题描述 投票:0回答:2

我想根据键值向文件添加一列。 我有 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

有人可以帮助我吗? 非常感谢。

loops for-loop awk key-value
2个回答
1
投票

您不需要进行 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

0
投票
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 中测试)

© www.soinside.com 2019 - 2024. All rights reserved.