使用 awk 输出作为条件语句

Ger*_*nas 1 bash awk

我有一些具有以下格式的数据:

 2     1  500  500  500
 3     1  500  500  500
 6     1  500  500  500
 8     1  500  500  500
 9     1  500  500  500
11     1  500  500  500
12     1  500  500  500
14     1  500  500  500
15     1  500  500  500
16     1  500  500  500
17     1  500  500  500
20     1  500  500  500
21     1  500  500  500
23     1  500  500  500
24     1  500  500  500
25     1  500  500  500
27     1  500  500  500
30     1  500  500  500
31     1  500  500  500
32     1  500  500  500
33     1  500  500  500
34     1  500  500  500
35     1  500  500  500
38     1  500  500  500
40     1  500  500  500
41     1  500  500  500
43     1  500  500  500
44     1  500  500  500
46     1  500  500  500
47     1  500  500  500
Run Code Online (Sandbox Code Playgroud)

我只想将第一列等于 11-40 的行中的 500 值更改为 100。现在我正在做类似的事情:

Numbers=($(seq 11 1 40))
File=filename.txt
for i in ${Numbers[*]}
do
        if [ $i == awk '{print $1}' $File ];then
        NumberLine=$(grep -n $i $File | cut -d : -f 1)
        sed -i "${NumberLine}s/500/100/" $File
        fi
done
Run Code Online (Sandbox Code Playgroud)

单独而言,每一行似乎都做了我想做的事情,但是当我将它们放入循环中时,出现以下错误:

./changeRestraints.sh: line 5: [: too many arguments

我怀疑这与我的 awk 作为条件语句的一部分有关。我该如何解决这个问题以使该脚本运行?

谢谢你,

tsh*_*ono 5

为了提高效率,在循环中重复调用awkand并不是一个好主意。sed请尝试:

awk '$1>10 && $1<=40 {gsub(/\<500\>/, "100")} 1' filename.txt
Run Code Online (Sandbox Code Playgroud)

请注意正则表达式\<和与单词边界匹配的扩展名\>GNU awk

[编辑]
gsub()函数是一个变体,sub()它替换多次出现的匹配字符串,同时sub()仅替换第一个匹配项。sub()和之间的关系gsub()类似于中s/regex/repl/和 的关系。s/regex/repl/gsed

如果你想使用变量来表示嵌入的数字,你可以利用-v varname=value通过命令行选项分配 awk 变量的机制:

#!/bin/bash

start=11    # bash variables
stop=40
from=500
to=100
awk -v start="$start" -v stop="$stop" -v from="$from" -v to="$to" '$1>=start && $1<=stop {gsub("\\<" from "\\>", to)} 1' filename.txt
Run Code Online (Sandbox Code Playgroud)
  • 当 assiging 时-v start="$start",lhsstart是 awk 变量名,rhs"$start"是 bash 变量。我们可以为它们使用相同的名称(尽管它们看起来很混乱)。您还可以为变量分配立即值,例如-v start=11
  • 由于我们不能使用正则表达式引用/regex/来包含 awk 变量,因此我们需要改为说"\\<" from "\\>"。之间的空格只是为了可读性,它相当于"\\<"from"\\>".