【问题标题】:sed - insert line after match with a double tab for the beginning of inserted linesed - 匹配后插入行,插入行开头的双制表符
【发布时间】:2017-06-15 21:21:58
【问题描述】:

我有以下 input.txt :

        "loop:\n\t" 
        "add %%g1, 1, %%g1\n\t" 

我想在第一行和第二行之间插入一行以获得:

    "loop:\n\t" 
    "add %%g1, 1, %%g1\n\t" 
    "add %%g1, 1, %%g1\n\t" 

这是我尝试过的:

sed '/loop\:/a "\t \t add %%g1, 1, %%g1\\n\\t"' input.txt

但是有了这个,我得到:

        "loop:\n\t" 
"       add %%g1, 1, %%g1\n\t" 
        "add %%g1, 1, %%g1\n\t" 

如您所见,插入行的第一个引号位于行首,而不是在add 字之前。

如何规避这个问题?

谢谢

更新 1:

我意识到每行开头和第一个字符之间的空格不是制表符,而是经典空格。

然后,我尝试使用这个解决方案(来自this link

awk '{print} /loop\:/{ print substr($0,1,match($0,/[^[:space:]]/)-1) "add %%g1, 1, %%g1\n\t"}' input.txt

似乎这个命令行从上一行计算了正确的缩进,但不幸的是,我得到了这个:

           "loop:\n\t" 
"add %%g1, 1, %%g1\n\t" 
           "add %%g1, 1, %%g1\n\t" 

而我想要:

           "loop:\n\t" 
           "add %%g1, 1, %%g1\n\t" 
           "add %%g1, 1, %%g1\n\t" 

你能看到错误吗?

问候

【问题讨论】:

  • 如果那个 awk 脚本产生了那个输出,那么你的 awk 就会以非常具体和神奇的方式严重破坏(我非常怀疑)。 print ... "add %%g1, 1, %%g1\n\t" 只是 不能 输出 "add %%g1, 1, %%g1\n\t",因为您传递给 print 的字符串不包含双引号,也不会转义反斜杠。

标签: awk sed


【解决方案1】:

sed 用于在单个行上进行简单替换,仅此而已。对于任何更有趣的事情,只需使用 awk 来代替软件的清晰度、可移植性、效率和大多数其他理想属性:

$ awk '{print} /loop:/{print "\t\"add %%g1, 1, %%g1\\n\\t\""}' file
        "loop:\n\t"
        "add %%g1, 1, %%g1\n\t"
        "add %%g1, 1, %%g1\n\t"

以上只是实现了您尝试使用 sed 执行的操作,但根据您的实际要求可能有更好的方法,例如这些中的任何一个都具有上述优势,但在不同条件下产生相同的输出:

$ awk '1;NR==2' file
        "loop:\n\t"
        "add %%g1, 1, %%g1\n\t"
        "add %%g1, 1, %%g1\n\t"


$ awk '{print} f{print;f=0} /loop:/{f=1}' file
        "loop:\n\t"
        "add %%g1, 1, %%g1\n\t"
        "add %%g1, 1, %%g1\n\t"

$ awk '{print} /loop:/{sub(/".*/,""); print $0 "\"add %%g1, 1, %%g1\\n\\t\""}' file
        "loop:\n\t"
        "add %%g1, 1, %%g1\n\t"
        "add %%g1, 1, %%g1\n\t"

根据您在a previous answer of mine 下留下的评论,听起来您确实想要其中一个底部,因此您不必指定缩进。

【讨论】:

  • 感谢您的回答。你能否给我一些关于我使用的命令的详细信息: **awk '{print} /loop:/{sub(/".*/,""); print $0 "\"add %%g1, 1 , %%g1\\n\\t\""}' ** . 你用"loop:" + "add %%g1, 1, %%g1\\n\\t 替换块"loop:" \"" ??
  • 不客气。 sub(/".*/,"") 删除 loop: 行上第一个 " 之后的所有内容(因此只留下前导空格缩进),然后 print $0 "..." 打印该空格,然后是新字符串。
  • 最后一个问题:在这个命令中,如何插入新行“add %%g1 ....”,我的意思是,循环行后的回车在哪里?谢谢
  • 循环线已经被{print} lust 打印出来了,就像所有其他现有的线都被那个语句打印出来一样,现在我们再次在循环线(/loop:/)上操作以剥离" on 并在再次打印之前添加新字符串。
【解决方案2】:

使用 GNU sed:

先用反斜杠转义\t

sed '/loop\:/a \\t "add %%g1, 1, %%g1\\n\\t"' file

或搜索和替换:

sed 's/loop\:.*/&\n\t "add %%g1, 1, %%g1\\n\\t"/' file

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-11
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多