【问题标题】:N-Insert In SedN-Insert In Sed
【发布时间】:2011-01-18 12:06:54
【问题描述】:

如何使用 sed 将每行的前 150 个字符替换为空格。我不想拿出大炮(Python、Perl 等),而且 sed 本身似乎非常强大(例如,有些人在其中编写了 dc 计算器)。一个相关的问题是在每行前面插入 150 个空格。

s/^.\{50\}/?????/

匹配前 50 个字符,然后呢?我不能输出

s/^.\{50\}/ \{50\}/

可以使用 readline 来模拟 150 次按下 (alt+150, ),但这很糟糕。

【问题讨论】:

    标签: regex insert replace sed


    【解决方案1】:

    基本上你想这样做:

    sed -r "s/^.{150}/$(giveme150spaces)/"
    

    问题是以编程方式获得 150 个空格的最优雅的方式是什么。这里讨论了各种技术:Bash Hacker's Wiki。最简单的就是使用printf '%150s',像这样:

    sed -r "s/^.{150}/$(printf '%150s')/"
    

    【讨论】:

    • 能否将 printf 解决方案应用于 OP 对使用 sed 的解决方案的请求?
    【解决方案2】:

    使用保留空间。

    /^.\{150\}/ {;# simply echo lines shorter than 150 chars
        h;# make a backup
        s/^.\{150\}\(.*\)/\1/;# strip 150 characters
        x;# swap backup in and remainder out
        s/^\(.\{150\}\).*/\1/;# only keep 150 characters
        s/./ /g;# replace every character with a space
        G;# append newline + remainder to spaces
        s/\n//;# strip pesky newline
    };
    

    或者,您可以编写一个循环(代码稍微短一些):

    s/^.\{150\}/x/;# strip 150 characters & mark beginning of line
    t l
    # if first substitution matched, then loop
    d; # else abort and go to next input line
    :l
    # begin loop
    s/^/ /;# insert a space
    /^ \{150\}x/!t l
    # if line doesn't begin with 150 spaces, loop
    s/x//;# strip beginning marker
    

    但是,我认为您不能在没有sed -f 的情况下使用循环,或者找到其他方式来逃避换行符。标签名称似乎一直延伸到行尾,一直到 ;

    【讨论】:

    • 同上,有一些更正:sed -n '/^.\{150\}/ {h; s/^.\{150\}\(.*\)/\1/; x; s/^\(.\{150\}\).*/\1/; s/./ /g; G; s/\n//; p}' 原始将行的两部分打印在不同的行上(换句话说,添加了一个额外的换行符,在第一组大括号上缺少反斜杠并且不包括必要的“-n”。无论如何,+1。
    • @Elite, @Dennis:很抱歉让你们工作,显然我在几个人阅读答案后几秒钟就发布了我的更正:vP - 看起来我的更正与你的代码相同,Dennis , 在短线上给予或接受行为。
    • @levis:比如?其他答案都使用其他工具。
    • @Pot。 sed 使用正则表达式和小字母字符来表示特定操作。虽然代码可能很简洁,可以做你想做的事,但太多的代码加上 regex 会使代码不易阅读和理解。
    • @levis:所以你对我投了反对票,因为当我解决一个难题时它看起来很丑?不管是否存在更漂亮的解决方案?
    【解决方案3】:

    逻辑是迭代文件,打印 150 个空格,然后使用“substringing”打印从 151 到结尾的其余行。例如前 10 个字符。

    $ more file
    1234567890abc
    0987654321def
    $ awk '{printf "%10s%s\n", " ",substr($0,11)}' file
              abc
              def
    

    这比制作正则表达式要简单得多。

    重击:

    while read -r line
    do
        printf "%10s%s\n" " " "${line:10}"
    done <"file"
    

    【讨论】:

      【解决方案4】:

      这可能对你有用:

      sed ':a;/^ \{150\}/!{s/[^ ]/ /;ta}' file
      

      这会将一行的前 150 个字符替换为空格。但是,如果该行短于 150,则将其全部替换为空格,但保留原始长度。

      此解决方案将前 150 个字符替换为空格或将行增加到 150 个空格:

      sed ':a;/^ \{150\}/!{s/[^ ]/ /;ta;s/^/ /;ba}' file
      

      这会将一行的前 150 个字符替换为空格,但保留较短的行不变:

      sed '/.\{150\}/!b:a;/^ \{150\}/!{s/[^ ]/ /;ta}' file
      

      【讨论】:

        猜你喜欢
        • 2016-01-16
        • 2011-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-26
        • 2018-04-17
        • 2019-04-09
        相关资源
        最近更新 更多