使用 sed 从一行剪切文本并将其附加到另一行

问题描述 投票:0回答:1

我在使用 sed 进行涉及多行模式的就地文本替换时遇到困难。我特别需要从一行中剪切一个模式并将其附加到另一行上第一次出现的另一个模式的末尾。当文本附加到包含第二个图案的行时,还需要在要粘贴的图案的两侧添加一些附加文本。

就我而言,搜索范围如下:

/^find.* | while/,/^done/

| while
之前的所有文字都需要剪切,然后粘贴到
^done
的末尾。

执行此操作时,粘贴的文本还应该被字符包围,如下所示:

 < <(
粘贴文本
)

最后,应移除线开头的管道:

/^| while/s/^| //

例如,如果文件包含以下内容:

find . -mindepth 1 -maxdepth 1 -printf "%P\n\0" | sort -z | while read -d $'\0' a
do
    cnt=$(( "${cnt}"+1 ))
    declare select"${cnt}"="${a}"
    name="${a}"
    echo "Type ${cnt} for ${name::-5}"
done

结果文本应该是:

while read -d $'\0' a
do
    cnt=$(( "${cnt}"+1 ))
    declare select"${cnt}"="${a}"
    name="${a}"
    echo "Type ${cnt} for ${name::-5}"
done < <(find . -mindepth 1 -maxdepth 1 -printf "%P\n\0" | sort -z)

请注意,正在更改的文件多次出现此类情况。这些替换将从 bash 脚本运行。

sed -i -e '<expression>' "$changeme"

在 sed 中可以做到这一点吗?非常感谢任何帮助!

sed
1个回答
0
投票

对于线组的具体情况,其中:

  • 第一行以
    find
    开头,然后包含
    | while
  • 最后一行以
    done
  • 开头

你可以尝试:

sed -i.old '
    /^find.* | while/,/^done/ {

        /^\(find.*\) | \(while.*\)/ {
            # create and store new final line
            h
            s//done < <(\1)/
            x

            # edit start line
            s//\2/
            b
        }

        # load new final line
        /^done/ x
    }

    # print (possibly-edited) line

' file

可以重新排列代码以避免两次指定起始行正则表达式。

© www.soinside.com 2019 - 2024. All rights reserved.