【问题标题】:Insert blank line before line matching pattern in sed在 sed 中的行匹配模式之前插入空行
【发布时间】:2017-08-10 17:33:14
【问题描述】:

当我们匹配一个模式时,我试图在一行上方插入空行。我们有一个 grep 语句,它将查找行并将行号存储在一个变量中。

在此示例中,我想在第 1 行上方插入一个空白行,即happy 行,然后在第 3 行上方插入一个包含文本 sad 的行。

这适用于 sed 命令,但是我想使用 variable 替换 sed 语句中的行号,这就是它失败的地方。让我继续并展示这个例子 我已创建以显示我遇到的问题。

这是我们的 sed 命令,在没有变量的情况下使用它:

sed '1i\\' test # insert blank line at top of file:

这是我们的文件名为:test,它有 3 行:

Line1=happy
Line2=mad
Line3=sad

sed 语句有两个变量:

1: this has the line of happy - which is 1.
2. this has the line of sad - which is 3.

这是我们希望sed 语句使用的变量:

h=$(grep -n happy test | cut -d : -f 1)
s=$(grep -n sad test | cut -d : -f 1)

表明hs 变量似乎有效:

user@host:~$ echo $h
1
user@host:~$ echo $s
3

表明我们的sed 语句可以正常工作以在文件开头输出一个空行 - 这是第 1 行,然后也是第 3 行。

sed '1i\\' test  # we test that it outputs a blank line on the top of the file first - without our variable:

user@host:~$ sed '1i\\' test 
           # here is our blank line.
happy
mad
sad

user@host:~$ sed '3i\\' test
happy
mad
           # here is our blank line for line 3.
sad

现在我们继续使用在命令替换变量hs 中定义的变量对其进行测试,这样我们就可以尝试做与上面相同的事情。 这是它不起作用的地方 - 我不会同时测试这两个变量,因为它不适用于第一个变量。我尝试了不同的语法,我已经深入研究过,但无法让 sed 使用该变量。

sed "$si\\" test # try to insert the blank line with the variable at top of file


user@host:~$ sed '$hi\\' test # we test that it outputs a blank line on the top of the file first - with our variable with  ticks ' ':
sed: -e expression #1, char 3: extra characters after command  

user@host:~$ sed "$hi\\" test # we test that it outputs a blank line on the top of the file first - with our variable with  quotes " " :
sed: -e expression #1, char 1: unterminated address regex


user@host:~$ sed "'$hi\\'" test # we test that it outputs a blank line on the top of the file first - with our variable with  quotes/ticks "' '" :
sed: -e expression #1, char 1: unknown command: `''

我尝试了几种其他形式的引号/记号等来尝试让它发挥作用。我仔细阅读了堆栈溢出,发现如果使用变量,我应该在命令周围使用引号。

我得到了一条评论,可以在我的变量周围使用 { },但是这样做时它不会像使用真实文本那样在上面输出一行:

user@host:~$ sed "${h}i\\" test # the command does not error now but does not output the line either - variable h.
happy
mad
sad

user@host:~$ sed "${s}i\\" test # the command does not error now but does not output the line either - variable s.
happy
mad
sad

user@host:~$ sed '1i\\' test
        # blank line here
happy
mad
sad

【问题讨论】:

  • ${g}i, ${h}i; shell 正在寻找不存在的变量$gi$hi。或者,$g i$h i
  • 它适用于 "${gi,\\" 测试 - 因为在命令中不会出错,但它不会在第一行上方输出一行。
  • 哦,由于使用双引号,您实际上需要转义反斜杠:"${g}i\\\\"
  • 您不应使用已接受的答案更新您的问题。答案已经存在。

标签: bash awk sed command


【解决方案1】:

使用grep 获取行号以便您可以将其传递给sed 是一种反模式。您想在sed 中进行所有处理。

sed -e '/happy/i\\' -e '/sad/i\\' file

如果两种情况下的操作确实相同,您可以将其合并为一个正则表达式。

sed '/\(happy\|sad\)/i\\' file

(精确的语法在sed 方言之间会有所不同,但你明白了。如果你的sed-r-E,你可以避免使用反斜杠。)

【讨论】:

  • 我将在我的问题中添加另一个编辑以显示更大的图景。我正在使用这种方式编写脚本,添加一个空白行,我可以用它来通过脚本输入文本。
【解决方案2】:

您的第一个问题是"$gi" 正在寻找不存在的变量$gi。为避免这种情况,您必须在变量名周围加上花括号,如 "${g}i",或者在变量名和 sed 命令之间放置一个空格,如 "$g i"

然后,因为您的测试使用单引号,所以双反斜杠按字面意思解释。在双引号中,反斜杠必须被转义,导致

sed "${h}i\\\\" test

最后,这似乎过于复杂了。要在包含模式的行之前插入一个空行,您可以使用它(例如 happy):

sed '/happy/s/^/\n/' test

如果该行匹配happy,这会将行首“替换”为换行符。

请注意,像这样插入换行符不适用于每个 sed;对于 macOS sed,你可能会使用类似的东西

sed 'happy/s/^/'$'\n''/' test

【讨论】:

  • 它过于复杂,因为现实世界的文件将有 1000 行,我需要将特定的东西与变量匹配并使用变量来做其他事情。
  • 听起来你应该改写一个 Awk 脚本。
【解决方案3】:

这应该可以完美运行。我在 Ubuntu 上测试过,没有任何问题。

number=3
sed $number'i\\' test.txt

问候!

【讨论】:

  • 这是可行的,因为双反斜杠在单引号内。
  • 是的。确切地。 :)
  • user@host:~$ sed $h'i\\' test #空行快乐疯狂悲伤
  • 你如何反转这个并在模式之后的下一行添加一个空行?
  • @AlexTomko a\\
猜你喜欢
  • 1970-01-01
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
相关资源
最近更新 更多