Regex 将前导空格替换为sed(或类似)

Regex 将前导空格替换为sed(或类似),regex,bash,unix,sed,Regex,Bash,Unix,Sed,我想用相同数量的其他字符替换文件每行的前导空格或制表符(为了简单起见,我们使用u) 例如 变成 foo bar _foo bar __line 3 请注意,非领先的whitepsace不受影响,否则这将很容易!我怀疑这仍然很容易,但我错过了窍门。Perl一行程序行吗?你可以写: perl -pe 's/^([ \t]+)/"_" x length $1/e' (在标准输入时在文件中设置管道,或在cmomand末尾指定文件名) 编辑添加:William Pursell在上面的评论中询问您是希望

我想用相同数量的其他字符替换文件每行的前导空格或制表符(为了简单起见,我们使用u)

例如

变成

foo bar
_foo bar
__line 3

请注意,非领先的whitepsace不受影响,否则这将很容易!我怀疑这仍然很容易,但我错过了窍门。

Perl一行程序行吗?你可以写:

perl -pe 's/^([ \t]+)/"_" x length $1/e'
(在标准输入时在文件中设置管道,或在cmomand末尾指定文件名)

编辑添加:William Pursell在上面的评论中询问您是希望“一个选项卡被替换为一个“\ux”,还是足够填写一个tabstop”。上面的命令将用一个下划线替换选项卡。如果您想填写一个tabstop,最简单的方法是使用
expand
实用程序,将制表符转换为空格,然后再将输入传递给Perl:

expand -i | perl -pe 's/^([ \t]+)/"_" x length $1/e'

(在标准输入时在文件中添加管道,或者在
展开
部分的末尾,即
|
字符之前指定文件名)。

您可以使用此正则表达式获取前导空格或制表符

(^\s+)

但是,用下划线替换它,我无法帮助,因为我没有bash方面的经验,这将适用于您:

sed ':a;s/^\([[:space:]]*\)[[:space:]]/\1_/;ta' file
sed '/^\s\+/!b;h;s///;x;s/\S.*//;s/./_/g;G;s/\n//' <<<$'foo bar\n foo bar\n\t\tline 3'
foo bar
_foo bar
__line 3
例子
$sed”:a;s/^\([[:space:]*\)[[:space:]/\1_/;ta'这可能适合您:

sed ':a;s/^\([[:space:]]*\)[[:space:]]/\1_/;ta' file
sed '/^\s\+/!b;h;s///;x;s/\S.*//;s/./_/g;G;s/\n//' <<<$'foo bar\n foo bar\n\t\tline 3'
foo bar
_foo bar
__line 3

sed'/^\s\+/!BHs//;x;s/\s.*/;s//ug/g;Gs/\n/'@SiegeX的解决方案不适用于Mac OS X Lion上的系统
sed
。这里有一个解决方法:

eval sed "$(for i in $(seq 40 -1 1); do
                  echo -n "-e 's/^$(for j in $(seq 1 $i);
                      do echo -n ' ';
                  done)/$(for j in $(seq 1 $i);
                      do echo -n '_';
                  done)/' "; done)"
它动态地生成选项

...
-e 's/^       /_______/g' \
-e 's/^      /______/g' \
-e 's/^     /_____/g' \
-e 's/^    /____/g' \
-e 's/^   /___/g' \
-e 's/^  /__/g' \
-e 's/^ /_/g'

制表符是否被替换为一个“u”,或者足以填充制表符?如果一行已经以一个或多个下划线开头,后跟空格,则会在不应该添加下划线的地方添加下划线。它相对容易被重新编译,不过:
sed'/^[[:space:]/{:a;s/\(\u*\)[[:space:]/\1\uu/\ta;}'
@JonathanLeffler谢谢,打了个好电话,回答更新了。一个小小的变化是,
^
锚仍然需要在
s
命令中使用,以防止单词之间的空格变成下划线。在转录我修改后的
sed
脚本时键入错误:(有时候,要把每件事都做好是很困难的。你不需要排除正则表达式中的前导下划线,你只需要查找空格:
{:a;s/^\([[:space:]*\)[[:space:]/\1_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。(Glenn Jackman的建议可以解决这个问题。)在这种情况下不能使用perl,但无论如何都要投票支持一个工作解决方案,它显示了一个有趣的(而且可能比sed解决方案更有效)解决方案。
...
-e 's/^       /_______/g' \
-e 's/^      /______/g' \
-e 's/^     /_____/g' \
-e 's/^    /____/g' \
-e 's/^   /___/g' \
-e 's/^  /__/g' \
-e 's/^ /_/g'