【问题标题】:using sed "r" to search for text and append contents of file使用 sed "r" 搜索文本并附加文件内容
【发布时间】:2019-02-27 23:34:36
【问题描述】:

我相当精通使用 sed 的内联函数,以及它的替换能力以及使用不同字符作为其函数的分隔符,但我现在发现自己使用“r”函数来添加sed 在目标文件中找到字符串后追加文件的内容。我相信这被称为“零地址或单地址”命令。

很简单,如果一个名为“letters”的文件包含

abc
def
ghi

而“数字”包含

123

然后使用

sed -i "def r numbers" letters

导致“字母”变成

abc
def
123
ghi

所以,我的问题是:如果“字母”包含正斜杠会怎样?例如, letters2 包含:

/abc/def/ghi
/def/ghi/jkl
/ghi/jkl/mno

我想在“/def/ghi/jkl”字符串之后附加“数字”?最初认为一个简单的

sed -i '/def/ghi/jkl r numbers' letters2

就足够了,但当然使用正斜杠,它会使事情变得更加复杂,考虑到这会导致“命令后的额外字符”错误。在这种情况下,您似乎不能像在(例如)事物的替换方面那样表示符号。我已经尝试过(以多种不同的方式),例如:

sed -i '@/def/ghi/jkl@ r numbers' letters2

但我不断收到“未知命令:@”错误。

我在网上找不到任何东西,也找不到关于如何克服这个问题的手册。任何帮助将不胜感激!

【问题讨论】:

    标签: sed string-substitution


    【解决方案1】:

    r 命令前面可以有零个或一个地址。

    来自documentation of sed:

    Sed 地址

    地址不是必需的,但如果指定必须是一个数字(在输入文件中累积输入行数),一个美元 ('$') 字符 处理输入的最后一行,或上下文地址(由正则表达式前后加分隔符组成)。

    您的示例不使用数字或$ 作为地址说明符。唯一剩下的选项是用分隔符括起来的正则表达式。 sed 中 regex 的默认分隔符是正斜杠 (/)。

    由于/ 是regex 定界符,因此regex 内任何/ 的使用都需要转义(即前面有\)。
    你需要的命令是:

    sed -i '/\/def\/ghi\/jkl/ r numbers' letters2
    

    要为正则表达式使用不同的分隔符(以避免需要转义正斜杠),当它用作开放分隔符时(在地址之前),您必须在其前面加上反斜杠。在regex 之后使用时不要转义。在regex 中转义它告诉sed 使用它的字面意思。

    本例中的命令是:

    sed -i '\@/def/ghi/jkl@ r numbers' letters2
    

    您声称有效的示例 (sed -i "def r numbers" letters) 不遵循此模式,并且实际上不起作用(至少在我使用的 macOS sed 上)。
    应该是sed -i "/def/ r numbers" letters,或者更准确地说是sed -i "/^def$/ r numbers" letters。

    【讨论】:

      【解决方案2】:

      sed 非常适合 s/old/new,但对于其他任何东西,只需使用 awk:

      $ awk 'NR==FNR{new=new $0 ORS; next} {print} $0=="/def/ghi/jkl"{printf "%s", new}' numbers letters
      /abc/def/ghi
      /def/ghi/jkl
      123
      /ghi/jkl/mno
      

      对于任何输入文件的任何内容,以上内容都适用于任何 UNIX 机器上的任何 shell 中的任何 awk。它只是通过一次读取一行 numbers 并连接来创建一个名为“new”的变量,然后读取 letters 并打印当前行,然后打印 new 的内容,如果当前行是你的字符串重新感兴趣。

      【讨论】:

        猜你喜欢
        • 2014-02-18
        • 2014-04-12
        • 1970-01-01
        • 2015-11-13
        • 2011-05-25
        • 2016-04-04
        • 1970-01-01
        • 2016-10-08
        • 1970-01-01
        相关资源
        最近更新 更多