shell 使用 通过 awk 创建 的 数组 作为 另 一 个 awk 脚本 中 的 变量

iqjalb3h  于 2022-11-16  发布在  Shell
关注(0)|答案(3)|浏览(195)

我正尝试使用awk提取数据,使用一个条件语句,其中包含一个使用另一个awk脚本创建的数组。
我用于创建数组的awk脚本如下所示:

array=($(awk 'NR>1 { print $1 }' < file.tsv))

然后,在其他awk脚本中使用此数组

awk var="${array[@]}"  'FNR==1{ for(i=1;i<=NF;i++){ heading[i]=$i } next } { for(i=2;i<=NF;i++){ if($i=="1" && heading[i] in var){ close(outFile); outFile=heading[i]".txt"; print ">kmer"NR-1"\n"$1 >> (outFile) }}}' < input.txt

但是,当我运行该程序时,出现以下错误。

awk: fatal: cannot open file 'foo' for reading (No such file or directory)

我已经看了很多关于为什么会出现这个错误以及如何正确处理implement a shell variable in awk的帖子,但是到目前为止,这些帖子都没有起作用。

awk 'FNR==1{ for(i=1;i<=NF;i++){ heading[i]=$i } next } { for(i=2;i<=NF;i++){ if($i=="1"){ close(outFile); outFile=heading[i]".txt"; print ">kmer"NR-1"\n"$1 >> (outFile) }}}' < input.txt

我真的需要那个条件语句,但是不知道我在awk中实现bash变量时做错了什么,希望能得到一些帮助。
提前感谢。

7ajki6be

7ajki6be1#

该特定错误消息是因为您在var=前面忘记了-v(它应该是awk -v var=,而不仅仅是awk var=),但是正如其他人所指出的,您不能在awk命令行上设置数组变量。还要注意,代码中的array是一个shell数组,而不是awk数组,和awk是两个完全不同的工具,每个工具都有自己的语法、语义、作用域等。
下面是如何真正做到你想做的事情:

array=( "$(awk 'BEGIN{FS=OFS="\t"} NR>1 { print $1 }' < file.tsv)" )

awk -v xyz="${array[*]}" '
    BEGIN{ split(xyz,tmp,RS); for (i in tmp) var[tmp[i]] }
    ... now use `var` as you were trying to ...
'

例如:

$ cat file.tsv
col1    col2
a b     c d e
f g h   i j
$ cat -T file.tsv
col1^Icol2
a b^Ic d e
f g h^Ii j
$ awk 'BEGIN{FS=OFS="\t"} NR>1 { print $1 }' < file.tsv
a b
f g h
$ array=( "$(awk 'BEGIN{FS=OFS="\t"} NR>1 { print $1 }' < file.tsv)" )
$ awk -v xyz="${array[*]}" '
    BEGIN {
        split(xyz,tmp,RS)
        for (i in tmp) {
            var[tmp[i]]
        }
        for (idx in var) {
            print "<" idx ">"
        }
    }
'
<f g h>
<a b>
yiytaume

yiytaume2#

在单个awk中处理这两个文件更容易、更高效:

**编辑:**已修复评论中的问题,谢谢@EdMorton

awk '
    FNR == NR {
        if ( FNR > 1 )
            var[$1]
        next
    }
    FNR == 1 {
        for (i = 1; i <= NF; i++)
            heading[i] = $i
        next
    }
    {
        for (i = 2; i <= NF; i++)
            if ( $i == "1" && heading[i] in var) {
                outFile = heading[i] ".txt"
                print ">kmer" (NR-1) "\n" $1 >> (outFile)
                close(outFile)
            }
    }
' file.tsv input.txt
t98cgbkg

t98cgbkg3#

您可以将字符串存储在变量中,然后使用split function将其转换为数组,请考虑以下简单示例,假设file1.txt内容为

A B C
D E F
G H I

file2.txt含量是

1
3
2

然后

var1=$(awk '{print $1}' file1.txt)
awk -v var1="$var1" 'BEGIN{split(var1,arr)}{print "First column value in line number",$1,"is",arr[$1]}' file2.txt

给出输出

First column value in line number 1 is A
First column value in line number 3 is G
First column value in line number 2 is D

说明:我存储第一个awk命令的输出,然后将其用作第二个awk命令中split函数的第一个参数。免责声明:此解决方案假定所有涉及的文件都具有符合默认GNU AWK行为的分隔符,即一个或多个空格始终是分隔符。

  • (在gawk 4.2.1中测试)*

相关问题