Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell Sed:在一行中使用a、c或i_Shell_Unix_Sed - Fatal编程技术网

Shell Sed:在一行中使用a、c或i

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

我经常在sed脚本中使用a和I,但如何在一行中使用它们(或者更具体地说,表示文本的结尾)

我试着引用文本,添加一个新行字符来表示文本的结尾,跳过新行;什么都不起作用,sed只是将shell行末尾的所有字符视为要处理的文本

当您有其他后续操作时,这会导致问题,因为它们被视为文本,而不是sed要执行的命令,例如p

这很好:

/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
命令,那么您就放弃了“一行”选项。如果您觉得必须并且正在使用GNU
sed
,您可以将每个“行”放在一个单独的
-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