【问题标题】:Moving matching lines in a text file using sed使用 sed 移动文本文件中的匹配行
【发布时间】:2019-03-14 02:15:59
【问题描述】:

我正在关注帖子

How to move specified line in file to other place with regexp match (bash script)?

到我的示例文件

asdasd0
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd2
asdasd3
asdasd4
DEFAULTS {
asdasd6

最终的输出应该是这样的

asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd6

我已经尝试了以下

sed "/-SRC_OUT_DIR.*/d;/DEFAULTS { /a"$(sed -n '/-SRC_OUT_DIR.*/p' test.txt)  test.txt`

但它不起作用。我得到以下输出

sed:can't read =: No such file or directory
sed:can't read "/a/b/c/d/e/f/g": No such file or directory
asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR
asdasd6

我也想知道为什么我不能使用\1,\2来打印需要移动的行。我试过了,但它什么也没打印。如果我需要将多个匹配行移动到文件中的不同位置,我将如何编写 sed 命令?

【问题讨论】:

    标签: regex bash sed


    【解决方案1】:

    当您询问sed 解决方案时,我建议为此使用awk。 不建议使用大量 sed 命令的丑陋嵌套。尤其是因为您阅读了两次文件。

    这是一个 awk

    awk '/SRC_OUT_DIR/{t=$0;next}1;/DEFAULTS/{print t}' file
    

    它是如何工作的?

    awk 将逐行读取您的file。每行,它将一个接一个地执行以下三个命令:

    1. /SRC_OUT_DIR/{t=$0;next}:如果该行包含匹配SRC_OUT_DIR的子字符串,则将该行存储在变量t中并移动到next行(不要执行2和3)
    2. 1: 默认操作:打印该行
    3. /DEFAULTS/{print t}:如果当前行包含子字符串DEFAULTS,则打印存储在变量t中的行

    如果您要移动多条线(这只向下移动):

    awk '/pattern1/ {t[1]=$0;next}
         /pattern2/ {t[2]=$0;next}
         /pattern3/ {t[3]=$0;next}
         /target3/ { print t[3] }
         1
         /target1/ { print t[1] }
         /target2/ { print t[2] }' file
    

    注意pattern3 将在target3 之前打印。

    【讨论】:

    • 您能否解释一下语法,以便像我这样的新手和其他人能够理解。如何为多行执行此操作?
    • @tulamba 解释已添加。多行是什么意思?
    • 很棒的解释
    • @tulamba 如果这回答了问题,请随时接受和/或投票赞成答案。我注意到您没有对您的任何问题给予任何回答。建议这样做。支付它作为修辞格。看看stackoverflow.com/help/someone-answers
    • 多行意味着如果我必须将与模式匹配的多行移动到文件中的不同位置
    【解决方案2】:

    您可以将匹配的行存储在 hold 空间中,delete 它,然后将 append 保留空间存储到要插入的行之后:

    $ sed '/^-SRC_OUT_DIR/{h;d;};/^DEFAULTS {/G' infile
    asdasd0
    asdasd2
    asdasd3
    asdasd4
    DEFAULTS {
    -SRC_OUT_DIR = /a/b/c/d/e/f/g/h
    asdasd6
    

    【讨论】:

    • 有效!非常感谢!一个问题:这项工作但仅限于一行。是否可以移动与模式匹配的多行并将它们附加在匹配另一个模式的特定行之后(或之前)?例如,移动更多匹配 ^-SRC_OUT_DIR 的行并将它们全部移到 ^DEFAULTS 之后?
    • @Magallo 无需花费太多时间,sed '/^-SRC_OUT_DIR/{H;d;};/^DEFAULTS {/{G;s/\n//;}' 之类的就可以了; H 而不是 h 追加到保持空间而不是替换它;因为保留空间以空行开头,所以我们在使用G 附加到模式空间后删除该空行。
    猜你喜欢
    • 2023-01-24
    • 2016-10-08
    • 2014-09-21
    • 2017-03-20
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 1970-01-01
    相关资源
    最近更新 更多