我有大量制表符分隔的文本文件,其中第二列包含我感兴趣的乐谱:
test_score_1.txt
Title FRED Chemgauss4 File
24937 -6.111582 A
24972 -7.644171 A
26246 -8.551361 A
21453 -7.291059 A
test_score_2.txt
Title FRED Chemgauss4 File
14721 -7.322331 B
27280 -6.229842 B
21451 -8.407396 B
10035 -7.482369 B
10037 -7.706176 B
我想检查是否有分数小于我定义的数字的标题。
以下代码在脚本中定义了我的分数并起作用:
check_score_1
#!/bin/bash
find . -name 'test_score_*.txt' -type f -print0 |
while read -r -d $'\0' x; do
awk '{FS = "\t" ; if ($2 < -7.5) print $0}' "$x"
done
如果我尝试像 check_scores_2.sh "-7.5"
那样向 awk 传递一个参数,如 check_score_2.sh
所示,它会返回两个文件中的所有条目。
check_scores_2.sh
#!/bin/bash
find . -name 'test_score_*.txt' -type f -print0 |
while read -r -d $'\0' x; do
awk '{FS = "\t" ; if ($2 < ARGV[1]) print $0}' "$x"
done
最后,check_scores_3.sh
显示我实际上没有从命令行传递任何参数。
check_scores_3.sh
#!/bin/bash
find . -name 'test_score_*.txt' -type f -print0 |
while read -r -d $'\0' x; do
awk '{print ARGV[0] "\t" ARGV[1] "\t" ARGV[2]}' "$x"
done
$ ./check_score_3.sh "-7.5"
给出以下输出:
awk ./test_score_1.txt
awk ./test_score_1.txt
awk ./test_score_1.txt
awk ./test_score_1.txt
awk ./test_score_1.txt
awk ./test_score_2.txt
awk ./test_score_2.txt
awk ./test_score_2.txt
awk ./test_score_2.txt
awk ./test_score_2.txt
awk ./test_score_2.txt
我做错了什么?
最佳答案
在你的 shell 脚本中,shellscript 的第一个参数是 $1
。 .您可以将该值分配给 awk 变量,如下所示:
find . -name 'test_score_*.txt' -type f -exec awk -v a="$1" -F'\t' '$2 < a' {} +
讨论
您的 print0/while read 循环非常好。
-exec
find
提供的选项但是,它可以在没有任何显式循环的情况下运行相同的命令。命令
{if ($2 < -7.5) print $0}
可以选择性地简化为条件$2 < -7.5
.这是因为条件的默认操作是print $0
.请注意引用文献
$1
和$2
彼此完全无关。因为$1
在双引号中,shell 在 awk 命令开始运行之前 替换它。 shell 解释$1
表示脚本的第一个参数。因为$2
出现在单引号中,shell 不理会它,它由 awk 解释。 awk 将其解释为当前记录的第二个字段。
关于linux - 在 do 循环中将参数传递给 awk,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38256635/