我有一些具有以下格式的数据:
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 作为条件语句的一部分有关。我该如何解决这个问题以使该脚本运行?
谢谢你,
为了提高效率,在循环中重复调用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)
-v start="$start",lhsstart是 awk 变量名,rhs"$start"是 bash 变量。我们可以为它们使用相同的名称(尽管它们看起来很混乱)。您还可以为变量分配立即值,例如-v start=11。/regex/来包含 awk 变量,因此我们需要改为说"\\<" from "\\>"。之间的空格只是为了可读性,它相当于"\\<"from"\\>".