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

时间:2018-09-24 22:30:22

标签: arrays bash sed

我喜欢使用“ sed”命令从文件中删除连续的两行。 我可以使用以下语法删除单行,其中 变量“ index”保存行号:

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

由于我想删除连续的行,所以我做了测试 应该减少/增加变量的语法,但是我遇到了严重的替换错误。

附录 我不确定在哪里发布,但在对 这个问题我发现这种语法无法正常工作

(((index ++))或((index--))

3 个答案:

答案 0 :(得分:1)

如果只想要第一个,则在看到它时退出:

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

但是您似乎正在多次处理此文件。如果可以描述您的总体目标,则必须采用一种更简单的方法。

例如,如果您只是想删除匹配的行和下一行,但只有第一次,则可以使用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

使用GNU sed,您可以将+1用作地址范围内的第二个地址:

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

或者如果您想使用bash / ksh arithmetic expansion:请使用后递增运算符

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

请注意,由于管道的缘故,sed在子外壳中运行:即使索引值现在为5,这也发生在子外壳中。 sed命令结束后,当前shell中的index值为4。

答案 1 :(得分:1)

sed是执行s / old / new的正确工具,仅此。不是您要尝试做的是什么,为什么当有更多合适的工具可以更轻松地完成工作时,您为什么要强迫去做某事?

正确执行脚本的方法:

#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"

似乎要这样做:

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

例如:

$ 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

如果您只想删除第一个匹配项:

$ 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

或第二个:

$ 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

并跳过5行而不是2行:

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

只要使用正确的工具完成正确的工作,就不要挖孔用茶匙种树。

答案 2 :(得分:1)

与sed一起在单行删除中使用/连续两次/顺序/可以解决一些问题。

#delete command line 

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

#delete说明行

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