简体   繁体   English

将递减变量传递给“sed”命令时出现错误的替换错误

[英]Bad substitution error when passing decremented variable to “sed” command

I like to use "sed" command to delete two consecutive lines from a file. 我喜欢使用“sed”命令从文件中删除两个连续的行。 I can delete single line using following syntax where variable "index" holds the line number: 我可以使用以下语法删除单行,其中变量“index”包含行号:

sed -i "${index}d" "$PWD$DEBUG_DIR$DEBUG_MENU"

Since I like to delete consecutive lines I did test this syntax which supposedly decrements / increments the variable but I am getting a bad substitution error. 由于我想删除连续的行,我确实测试了这种语法,据说减少/增加了变量,但是我得到了一个糟糕的替换错误。

Addendum I am not sure where to post this , but during troubleshooting of this issue I have discovered that this syntax does not work as expected 附录我不知道在哪里发布这个,但在解决这个问题的过程中,我发现这种语法不能按预期工作

(( index++)) nor (( index-- )) ((index ++))nor((index--))

If you just want the first one, then quit when you see it: 如果您只想要第一个,那么当您看到它时退出:

sed -n "/$choice/ {=;q}" file

But you look like you're processing this file multiple times. 但是你看起来好像在多次处理这个文件。 There must be a simpler way to do it, if you can describe your over-arching goal. 必须有一种更简单的方法,如果你能描述你的主要目标。

For example, if you just want to remove the matched line and the next line, but only the first time, you can use awk: here we see "4" and "5" are gone, but "14" and "15" remain: 例如,如果你只想删除匹配的行和下一行,但只是第一次,你可以使用awk:这里我们看到“4”和“5”消失,但“14”和“15”仍然存在:

$ seq 20 | awk '/4/ && !seen {getline; seen++; next} 1'
1
2
3
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

With GNU sed, you can use +1 as the second address in an address range: 使用GNU sed,您可以使用+1作为地址范围中的第二个地址:

index=4
seq 10 | sed "$index,+1 d"

Or if you want to use bash/ksh arithmetic expansion : use the post-increment operator 或者,如果要使用bash / ksh 算术扩展 :使用后增量运算符

seq 10 | sed "$((index++)),$index d"

Note here that, due to the pipeline, sed is running in a subshell: even though the index value is now 5, this occurs in a subshell. 请注意,由于管道,sed在子shell中运行:即使索引值现在为5,这也会发生在子shell中。 After the sed command ends, index has value 4 in the current shell. sed命令结束后,index在当前shell中的值为4。

sed is the right tool for doing s/old/new, that is all . sed是做s / old / new的正确工具,就是这样 What you're trying to do isn't that so why are you trying to coerce sed into doing something when there's far more appropriate tools can do the job far easier? 你想要做的不是那么,那么为什么当你有更合适的工具可以更容易地完成工作时,你是否试图强迫sed做某事?

The right way to do what your script: 正确的方法来做你的脚本:

#retrieve first matching line number
index=$(sed -n "/$choice/=" "$PWD$DEBUG_DIR$DEBUG_MENU")
#delete matching line plus next line from file 
sed -i "/$index[1], (( $index[1]++))/"
"$PWD$DEBUG_DIR$DEBUG_MENU"

seems to be trying to do is this: 似乎试图这样做:

awk -v choice="$choice" '$0~choice{skip=2} !(skip&&skip--)' "$PWD$DEBUG_DIR$DEBUG_MENU"

For example: 例如:

$ seq 20 | awk -v choice="4" '$0~choice{skip=2} !(skip&&skip--)'
1
2
3
6
7
8
9
10
11
12
13
16
17
18
19
20

if you only want to delete the first match: 如果你只想删除第一场比赛:

$ seq 20 | awk -v choice="4" '$0~choice{skip=2;cnt++} !(cnt==1 && skip && skip--)'
1
2
3
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

or the 2nd: 或第二个:

$ seq 20 | awk -v choice="4" '$0~choice{skip=2;cnt++} !(cnt==2 && skip && skip--)'
1
2
3
4
5
6
7
8
9
10
11
12
13
16
17
18
19
20

and to skip 5 lines instead of 2: 并跳过5行而不是2行:

$ seq 20 | awk -v choice="4" '$0~choice{skip=5} !(skip&&skip--)'
1
2
3
9
10
11
12
13
19
20

Just use the right tool for the right job, don't go digging holes to plant trees with a teaspoon. 只需使用合适的工具做正确的工作,不要挖洞用茶匙种植树木。

Using sed with "index" in single line deletion twice in a row / sequentially / works and resolves few issues. 在单行删除中使用带有“索引”的sed连续两次/顺序/工作并解决一些问题。

#delete command line 

sed -i "${index}d" "$PWD$DEBUG_DIR$DEBUG_MENU" sed -i“$ {index} d”“$ PWD $ DEBUG_DIR $ DEBUG_MENU”

#delete description line #delete description line

sed -i "${index}d" "$PWD$DEBUG_DIR$DEBUG_MENU"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM