将每行末尾的每个空格字符替换为“_”

将每行末尾的每个空格字符替换为“_”

我想用“_”替换每行末尾的每个空格字符。我发现了一个关于前导空格的类似问题和答案。但未能重建它的尾随空白。这是链接:https://stackoverflow.com/questions/9222281/replace-leading-whitespace-with-sed-or-similar

如果有人能想到更快或更好的方法,那就太好了。我也很欣赏好的解释,因为这样我学得更快:)

Input:
foo bar
 foo bar oof
  line 3a  
  line fo a

Output:
foo bar_____
 foo bar oof
  line 3a___
  line fo a_

答案1

使用 GNU sed,用下划线替换 eol 处的所有空格:

sed ':x;s/ \( *\)$/_\1/;tx'  

答案2

使用 perl 更有效:

perl -lpe 's/(\s+)$/"_" x length($1)/e' input.txt

只需用尾随空格对每行进行一次替换,而不是循环。

答案3

使用 GNU awk 将第三个参数传递给 match() 和 gensub():

$ awk 'match($0,/(.*[^ ])(.*)/,a){$0=a[1] gensub(/ /,"_","g",a[2])} 1' file
foo bar_____
 foo bar oof
  line 3a___
  line fo a_

对于任何 awk:

$ awk 'match($0,/ +$/){tail=substr($0,RSTART,RLENGTH); gsub(/ /,"_",tail); $0=substr($0,1,RSTART-1) tail} 1' file
foo bar_____
 foo bar oof
  line 3a___
  line fo a_

要通过调整上面的 gawk 解决方案来替换前导空白:

$ awk 'match($0,/^( *)(.*[^ ])(.*)/,a){$0=gensub(/ /,"_","g",a[1]) a[2] gensub(/ /,"_","g",a[3])} 1' file
foo bar_____
_foo bar oof
__line 3a___
__line fo a_

答案4

如果你想尝试添加空格使线条均匀:

$ cat -A file
foo bar$
 foo bar oof$
  line 3a  $
  line fo a$

线条不均匀

perl -MList::Util=max -lne '
    push @lines, $_
}
END {
    $wid = max map {length} @lines;
    for $line (@lines) {
        $padded = sprintf "%-*s", $wid, $line;
        $padded =~ s/(\s+)$/"_" x length($1)/e;
        print $padded
    }
' file
foo bar_____
 foo bar oof
  line 3a___
  line fo a_

相关内容