如何通过 bash shell 变量将 !~(非)大小写传递给 awk 模式

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

我有以下名为 file.txt 的文件。

a,b,c,d
d,c,b,a

我想运行以下名为 test.txt 的文件:

#!/bin/bash

data=$(cat file.txt)

gib () {
        echo "$1" | awk -v var="$2" 'BEGIN{FS=OFS=","} {if ($1 var~ a) {print $0}}'
}

ti=$(!)

gib "${data}" "$ti"

我的目标是只打印:

d,c,b,a

一般来说,如何排除而不是包含 awk 模式。我已经在没有 if 构造的情况下使用 /a/ 和 $1 var~ /a/ 尝试过。但没有任何效果。

bash awk
4个回答
3
投票

不能将运算符或运算符的一部分放入变量中。

如果您想让它有条件地查找匹配或不匹配,您可以利用比较结果为 1 或 0(真或假)这一事实。所以传入你想要测试的结果。

#!/bin/bash

data=$(cat file.txt)

gib () {
    echo "$1" | awk -v var="$2" 'BEGIN{FS=OFS=","} ($1 ~ /a/) == var'
}

ti=0

gib "${data}" "$ti"

3
投票

这就是你可以做你要求做的事情的方法:

$ cat test.txt
#!/bin/bash

data=$(cat file.txt)

gib () {
        echo "$1" | awk 'BEGIN{FS=OFS=","} {if ($1 '"$2"'~ /a/) {print $0}}'
}

ti='!'

gib "${data}" "$ti"

$ ./test.txt
d,c,b,a

但我不会特别建议让 shell 变量扩展成为 awk 脚本的一部分,请参阅 @Barmar 的回答,了解解决此问题的一种可能的更好方法,并参阅如何在 awk 脚本中使用 shell 变量?了解一般如何在 awk 脚本中使用 shell 变量的值。


0
投票

一般来说,我如何排除而不是包含 awk 图案。

如果您希望跳过行匹配模式,您可以使用

next
语句,请考虑以下简单示例,让
file.txt
成为具有以下内容的间隔剪切文件

qw 1
er 2
ty 3
ui 4
op 5

并且您希望打印第二列值,同时忽略第一列以元音开头的行(理解为一次性:aieou)那么您可以通过

来做到这一点
awk '$1~/^[aieou]/{next}{print $2}' file.txt

提供输出

1
3

说明:如果第一列以

aieou
之一开头,则转到
next
行,防止其后执行任何操作,在本例中为
print
第二个字段。

(在 GNU Awk 5.1.0 中测试)


0
投票
echo '
a,b,c,d
d,c,b,a' | 

awk NF==1 FS='^a,'

d,c,b,a

将任何“非大小写”设置为您的

FS
。那么它不匹配的唯一方式是当没有额外的列被分割出来时,即
NF == 1

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