我正试图使用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)
我已经看过多篇关于为什么会出现这种错误以及如何在awk中正确实现shell变量的文章,但到目前为止,这些文章都不起作用。但是,当删除shell变量并运行脚本时,它确实有效。
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变量有什么错,希望能得到一些帮助。
提前Thx。
特定的错误消息是因为您忘记了-v
在var=
前面(它应该是awk -v var=
,而不仅仅是awk var=
(,但正如其他人所指出的,您不能在awk命令行上设置数组变量。还要注意,代码中的array
是shell数组,而不是awk阵列,shell和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>
在单个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
您可以将字符串存储在变量中,然后使用split
函数将其转换为数组,考虑以下简单示例,让file1.txt
内容为
A B C
D E F
G H I
CCD_ 9内容为
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
函数的第一个参数免责声明:此解决方案假设所有涉及的文件都具有符合默认GNUAWK
行为的分隔符,即一个或多个空白始终是分隔符。
(在gawk 4.2.1中测试(