【问题标题】:sed — joining a range of selected linessed — 加入一系列选定的行
【发布时间】:2012-09-24 03:44:27
【问题描述】:

我是sed 的初学者。我知道可以将一个命令(或一组命令)应用于一定范围的行,就像这样

sed '/[begin]/,/[end]/ [some command]'

其中[begin] 是一个正则表达式,指定范围的开始行,[end] 是一个正则表达式,指定范围的结束行(但包含在范围内)。

我正在尝试使用它来指定文件中的一系列行并将它们全部连接到一行中。这是我最好的尝试,但没有奏效:

sed '/[begin]/,/[end]/ {
N
s/\n//
}
'

我可以毫无问题地选择我想要的一组行,但我似乎无法将它们全部合并为一行。如果有人能指出我正确的方向,我将不胜感激。

【问题讨论】:

    标签: sed


    【解决方案1】:

    一种使用GNU sed的方式:

    sed -n '/begin/,/end/ { H;g; s/^\n//; /end/s/\n/ /gp }' file.txt
    

    【讨论】:

    • 非常感谢。我从没想过要使用储物空间;我从你的回答中学到了很多。
    • 请注意,这将丢弃所有其他行。请参阅下面@Thor 的答案以获得更强大的解决方案。
    【解决方案2】:

    如果您想选择一些线并加入它们,这很简单。使用 Steve's 答案或我的 pipe-to-tr 替代方案:

    sed -n '/begin/,/end/p' | tr -d '\n'
    

    如果您还想保留其他行,这会变得有点棘手。这是我的做法(使用 GNU sed):

    join.sed

    /\[begin\]/ {
      :a
      /\[end\]/! { N; ba }
      s/\n/ /g
    }
    

    所以这里的逻辑是:

    1. 遇到[begin] 行时,开始使用循环将行收集到模式空间中。
    2. 当找到[end] 时,停止收集并加入行列。

    例子:

    seq 9 | sed -e '3s/^/[begin]\n/' -e '6s/$/\n[end]/' | sed -f join.sed
    

    输出:

    1
    2
    [begin] 3 4 5 6 [end]
    7
    8
    9
    

    【讨论】:

    • 为什么不 sed -n '/begin/,/end/p' |压缩包|枪弹 | tr -d '\n' 时?
    • @Valer:我不确定我是否理解你的观点。但是,我添加了第二个示例,它能够在保留文件其余部分的同时加入选定的行。
    【解决方案3】:

    我喜欢你的问题。我也喜欢塞德。很遗憾,我不知道如何在 Sed 中回答您的问题;所以,和你一样,我在这里寻找答案。

    由于这里还没有出现 Sed 的答案,这里是如何在 Perl 中做到这一点:

    perl -wne 'my $flag = 0; while (<>) { chomp; if (/[begin]/) {$flag = 1;} print if $flag; if (/[end]/) {print "\n" if $flag; $flag = 0;} } print "\n" if $flag;'
    

    【讨论】:

    • 感谢您在 Perl 中的实现。想学有一阵子了,把它加到我的sn-ps代码合集中学习吧。
    猜你喜欢
    • 1970-01-01
    • 2013-11-11
    • 2018-11-25
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    相关资源
    最近更新 更多