Shell Sed:在一行中使用a、c或i
我经常在sed脚本中使用a和I,但如何在一行中使用它们(或者更具体地说,表示文本的结尾) 我试着引用文本,添加一个新行字符来表示文本的结尾,跳过新行;什么都不起作用,sed只是将shell行末尾的所有字符视为要处理的文本 当您有其他后续操作时,这会导致问题,因为它们被视为文本,而不是sed要执行的命令,例如p 这很好:Shell Sed:在一行中使用a、c或i,shell,unix,sed,Shell,Unix,Sed,我经常在sed脚本中使用a和I,但如何在一行中使用它们(或者更具体地说,表示文本的结尾) 我试着引用文本,添加一个新行字符来表示文本的结尾,跳过新行;什么都不起作用,sed只是将shell行末尾的所有字符视为要处理的文本 当您有其他后续操作时,这会导致问题,因为它们被视为文本,而不是sed要执行的命令,例如p 这很好: /RANGE_start/,/RANGE_end/{ s/foo/bar/ /RANGE_end/a \--- This is the end of the range
/RANGE_start/,/RANGE_end/{
s/foo/bar/
/RANGE_end/a \--- This is the end of the range block ---
p
}
这样做不行:
/RANGE_start/,/RANGE_end/{s/foo/bar/;/RANGE_end/a \--- This is the end of the range block ---; p}
输出在哪里
---这是范围块的结束---;p}
或者,因为我试图使用p,所以没有输出(假设sed以-n开头)
是否有一个特殊的字符可以传递给a、c和I来表示文本的结束
(顺便说一句,这不仅仅是一行代码,(在我问的另一个问题中)它还涉及到使用w将文本写入文件,而文本不会写入文件。)
[我怀疑我使用了上面的一些Gnu细节。]您是否试图用范围内的bar替换foo,并在范围的末尾打印一些文本?使用awk,您可以像在sed中一样使用范围编写:
awk '
/RANGE_start/,/RANGE_end/ {
sub(/foo/,"bar")
print
if (/RANGE_end/) {
print "--- This is the end of the range block ---"
}
}
'
但是awk也允许您使用变量,这样您就不会在使用范围时遇到重复的情况(注意,在下面的脚本中,范围仅测试一次):
考虑到通过使用标志指示何时在范围内来处理范围的想法,只需更改标志的设置/测试位置,即可选择打印范围开始/结束行(或任何其他行!),这是多么简单:
$ seq 1 10 | awk '/3/{f=1} f{print} /7/{f=0}'
3
4
5
6
7
$ seq 1 10 | awk 'f{print} /3/{f=1} /7/{f=0}'
4
5
6
7
$ seq 1 10 | awk '/3/{f=1} /7/{f=0} f{print}'
3
4
5
6
$ seq 1 10 | awk '/7/{f=0} f{print} /3/{f=1}'
4
5
6
sed非常适合在单独的行上进行简单的替换,但对于其他任何东西,为了清晰、简单、高效、可移植性和其他最理想的软件属性,您应该使用awk。您的标准
sed
是否为sed--version
生成输出?请将其添加到您的Q中。如果没有,并且您已经用unix
标记了您的Q,您的sed可能是一个旧版本,它要求\a\,i\,c\。
作为行上的最后一个字符,然后在单独的行上添加、插入或更改文本,直到空行终止该操作的“输入”。我认为,一句话被高估了。当您接管一些代码时,等到您必须改进其他人的一行程序时,您不会太喜欢它们,但是是的,有时由于其他工具的限制,您需要一行程序;-)。祝你好运“一班轮”是一个贬义词——它不是不惜一切代价实现的目标。在我的书中,如果您正在使用sed
中的a
、c
、i
命令,那么您就放弃了“一行”选项。如果您觉得必须并且正在使用GNUsed
,您可以将每个“行”放在一个单独的-e
参数中,除了最后一行外,其余都以反斜杠结尾:sed-e'1a\'-e'line1\'-e'line2和final'
——如果您使用的是BSD(Mac OS X)sed
,即使这样也不起作用。您始终可以将sed
脚本放入文件中,然后使用sed-f sed.script files*
使用脚本编辑文件。感谢您的详细回复,其中提供了一些使用awk方法的线索。我对sed很满意,所以倾向于有一种内在的偏见。我想我认为awk是一个“重量级选手”,所以如果我认为我的解决方案只需要轻量级的话,那么最好使用sed。在本例中,这是冗长sed脚本的一部分。这个问题让我感到奇怪,因为sed中如此全面和彻底地使用了新行char来描述记录,但它不适用于a、c和i。这几乎就像这三个命令是后来由第三方编写的,而不考虑sed的历史和做事方式。一个冗长的sed脚本
——永远不应该说的话;-)。我使用sed已经35年了,awk已经25年了。它们都是各自擅长的伟大工具。您真的应该在使用/学习awk上投入更多的时间,因为如果您使用的是sed结构而不是s、g和p(带-n),那么awk替代方案几乎在所有方面都会更好。我花了10多年的时间强迫sed+grep+shell+等去做他们不应该做的事情来解决这个问题。只需看看上述awk脚本与sed变体相比是多么简单、一致和可移植。
$ seq 1 10 | awk '/3/{f=1} f{print} /7/{f=0}'
3
4
5
6
7
$ seq 1 10 | awk 'f{print} /3/{f=1} /7/{f=0}'
4
5
6
7
$ seq 1 10 | awk '/3/{f=1} /7/{f=0} f{print}'
3
4
5
6
$ seq 1 10 | awk '/7/{f=0} f{print} /3/{f=1}'
4
5
6