Sed:在单行中使用 a、c 或 i [英] Sed: Using a,c or i in a one-liner

查看:45
本文介绍了Sed:在单行中使用 a、c 或 i的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我经常在 sed 脚本中使用 a 和 i,但是如何在单行(或者更具体地表示文本结束)中使用它们?

I use a and i in sed scripts often, but how to use them generally in a one-liner (or more specifically to signify end-of-the-text)?

我尝试引用文本,添加一个新行字符来表示文本的结尾,转义新行;没有任何作用,sed 只是将 shell 行末尾的所有字符视为要使用的文本.

I have tried quoting the text, adding a new line char to signify the end of the text, escaping the new line; nothing works, sed simply treats all chars to the end of the shell's line as being text to work with.

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

This causes a problem when you have other actions following, as they get treated as text and not commands for sed to execute, such as 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}

--- This is the end of the range block ---; p}

或者,因为我正在尝试使用 p,所以没有输出(假设 sed 以 -n 开头).

or, since I'm trying to use p, no output (assuming sed was started with -n).

是否有一个特殊的字符可以传递给 a、c 和 i 来表示文本结束?

Is there a special char I can pass to a, c and i to signify end-of-text?

(顺便说一句,这不仅仅是关于单行,(在我问的另一个问题中)这也是关于使用 w 写入文件,其中文本不会写入文件.)

(BTW, this isn't just about one-liners, (in a different question I ask) it's also about writing to a file using w where the text does not get written to the file.)

[我怀疑我在使用上面的一些 Gnu 细节.]

[I suspect I'm using some Gnu specifics above.]

推荐答案

您是否尝试将范围内的 foo 替换为 bar 并在范围末尾打印一些文本?使用 awk,您可以使用像您必须在 sed 中那样的范围来编写:

Are you trying to replace foo with bar inside a range and print some text at the end of the range? With awk you CAN write that using ranges like you HAVE to in sed:

awk '
/RANGE_start/,/RANGE_end/ {
    sub(/foo/,"bar")
    print
    if (/RANGE_end/) {
        print "--- This is the end of the range block ---"
    }
}
'

但是 awk 还允许您使用变量,这样您就不会在使用范围时处理所需的重复条件(注意 RANGE_end 在下面的脚本中只测试一次):

but awk also lets you use variables instead so you aren't stuck dealing with the duplicate conditions required when using ranges (note RANGE_end is only tested for once in the below script):

awk '
/RANGE_start/ { inRange = 1 }
inRange {
    sub(/foo/,"bar")
    print
    if (/RANGE_end/) {
        print "--- This is the end of the range block ---"
        inRange = 0
    }
}
'

考虑到通过使用标志来指示您何时在范围内来处理范围的想法,看看通过更改标志所在的位置来选择打印范围开始/结束行(或其他任何东西!)是多么简单设置/测试:

Given that idea of handling ranges by using a flag to indicate when you're in the range, look how simple it is to select printing the range start/end lines (or anything else!) by just changing where the flag is set/tested:

$ 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 is great for simple substitutions on individual lines but for anything else you should be using awk for clarity, simplicity, efficiency, portability, and most other desirable software attributes.

这篇关于Sed:在单行中使用 a、c 或 i的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆