![AWK 变量(引号中的 1)+ 条件](https://linux22.com/image/181466/AWK%20%E5%8F%98%E9%87%8F%EF%BC%88%E5%BC%95%E5%8F%B7%E4%B8%AD%E7%9A%84%201%EF%BC%89%2B%20%E6%9D%A1%E4%BB%B6.png)
我在网上看了很多awk -v a=$var1 ..'BEGIN{...
帖子,但还是不行。
详细信息如下:
在终端中,我可以.gtf
按预期对文件进行子集化。取自这里:
awk '{if($1=="chr22" && $4>21799011 && $5<21807847 && $3=="exon") print $0}' GRCh38.gtf
哪个按预期工作。
但是,当循环文件来执行此操作时,没有输出:
while read line; do
# stage coordinates to pull gtf info
chr_tmp=$(echo $line | awk '{print $1}')
chr=$(echo $chr_tmp | sed 's/^/"/;s/$/"/') # echo prints "chr22"
st=$(echo $line | awk '{print $2}')
sp_tmp=$(echo $line | awk '{print $3}')
sp=$(($sp_tmp + 1))
name=$(echo $line | awk '{print $5}')
awk -v chr="$chr" -v st="$st" -v sp="$sp" 'BEGIN {if($1==chr && $4>st && $5<sp && $3=="exon") print $0}' GRCh38.gtf > ${name}.gtf
done < circ.bed
这很奇怪,因为在 shell 中,当我手动分配变量时,awk 按预期打印它们:
barry@NUIG:~/Desktop/BED12$ echo $chr
"chr22"
barry@NUIG:~/Desktop/BED12$ echo $st
21799011
barry@NUIG:~/Desktop/BED12$ echo $sp
21807846
barry@NUIG:~/Desktop/BED12$ awk -v chr="$chr" -v st="$st" -v sp="$sp" 'BEGIN {print chr, st, sp}'
"chr22" 21799011 21807846
但在脚本之外也不起作用:
awk -v chr="$chr" -v st="$st" -v sp="$sp" 'BEGIN{if($1==chr && $4 > st && $5 < sp) print $0}' GRCh38.gtf
将它们放入 awk 命令中时没有输出。也许事实$1=="chr22"
必须用引号引起来,那就是把 awk 扔掉?也尝试过不带双引号-v chr=$chr
,删除BEGIN
无济于事。
答案1
这是因为在 中awk
,变量$1
、$2
等引用$1
每个记录中检测到的字段(即第一个字段)的值。
BEGIN
和代码块END
分别在读入任何数据进行解析之前和之后运行。
在BEGIN
代码块中,尚未读入任何数据,因此不会填充任何字段变量,因此所有相等性检查都将失败。
看看你的两个测试:
$ awk -v chr="$chr" -v st="$st" -v sp="$sp" 'BEGIN {print chr, st, sp}'
"chr22" 21799011 21807846
在这里,您将awk
变量设置为等于 shell 变量,并打印这些值。一切都很好。
$ awk -v chr="$chr" -v st="$st" -v sp="$sp" 'BEGIN{if($1==chr && $4 > st && $5 < sp) print $0}' GRCh38.gtf
这里没有代码块在从文件中读取的数据上运行 -它只是在读入任何数据之前与块.gtf
中的字段进行比较。BEGIN
您可能想要这样做:
$ awk -v chr="$chr" -v st="$st" -v sp="$sp" '{if($1==chr && $4 > st && $5 < sp) print $0}' GRCh38.gtf
这将为文件中的每一行运行检查并打印数据,因为检查和print
语句不再位于BEGIN
块中。
我还将检查拉到运行块之外,并使其仅在检查有效时才处理(在本例中为打印)该行:
$ awk -v chr="$chr" -v st="$st" -v sp="$sp" '$1==chr && $4 > st && $5 < sp {print $0}' GRCh38.gtf
答案2
谢谢大家的回复。抱歉,我的代表权太低,无法为大家投票。
awk -v chr="$chr" -v st="$st" -v sp="$sp" '$1==chr && $4 > st && $5 < sp {print $0}' GRCh38.gtf
&
awk -v chr="$chr" -v st="$st" -v sp="$sp" '{if($1==chr && $4 > st && $5 < sp) print $0}' GRCh38.gtf
工作了。
BEGIN
我在脚本中的错误(以及使用)是认为 awk 想要将chr
变量放在引号中,因为在终端中,此行有效:
awk '{if($1=="chr22" && $4>21799011 && $5<21807847 && $3=="exon") print $0}' GRCh38.gtf
这一个不:
awk '{if($1==chr22 && $4>21799011 && $5<21807847 && $3=="exon") print $0}' GRCh38.gtf