【发布时间】:2012-03-02 14:20:41
【问题描述】:
我想用相同数量的其他字符替换文件每一行的前导空格或制表符(为简单起见,我们使用 _)。
例如
foo bar
foo bar
line 3
变成
foo bar
_foo bar
__line 3
请注意,非领先的空白不受影响,否则这很容易!我怀疑这仍然很容易,但我错过了诀窍。
【问题讨论】:
-
制表符是否被替换为单个“_”,还是足以填写制表位?
我想用相同数量的其他字符替换文件每一行的前导空格或制表符(为简单起见,我们使用 _)。
例如
foo bar
foo bar
line 3
变成
foo bar
_foo bar
__line 3
请注意,非领先的空白不受影响,否则这很容易!我怀疑这仍然很容易,但我错过了诀窍。
【问题讨论】:
@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'
【讨论】:
这对你有用:
sed ':a;s/^\([[:space:]]*\)[[:space:]]/\1_/;ta' file
$ sed ':a;s/^\([[:space:]]*\)[[:space:]]/\1_/;ta' <<<$'foo bar\n foo bar\n\t\tline 3\n _ x'
foo bar
_foo bar
__line 3
__ x
【讨论】:
sed '/^[[:space:]]/{:a;s/\(_*\)[[:space:]]/\1_/;ta;}'.
s 命令中仍然需要^ 锚点,以防止单词之间的空格变成下划线。
sed 脚本时出现错误。 :( 有时很难把所有事情都做好。
{:a;s/^\([[:space:]]*\)[[:space:]]/\1_/;ta}
' _ x' 这样的东西会变成'___x' 而不是'__ x'。 (格伦杰克曼的建议可以解决这个问题。)
这可能对你有用:
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
将初始制表符扩展为空格,然后扩展为下划线:
expand -i <<<$'foo bar\n foo bar\n\t\tline 3' |
sed '/^\s\+/!b;h;s///;x;s/\S.*//;s/./_/g;G;s/\n//'
foo bar
_foo bar
________________line 3
【讨论】:
你还好吗?使用 Perl 单线?你可以写:
perl -pe 's/^([ \t]+)/"_" x length $1/e'
(在标准输入上的文件中进行管道传输,或者在命令末尾指定文件名)。
编辑添加:William Pursell 在上面的评论中询问您是否要“用单个 '_' 替换选项卡,或者足以填写一个制表位”。上面的命令将用单个下划线替换选项卡。如果您想填写一个制表位,最简单的方法是使用expand 实用程序,它将制表符转换为空格,然后将输入传递给 Perl:
expand -i | perl -pe 's/^([ \t]+)/"_" x length $1/e'
(在标准输入上的文件中进行管道传输,或者在 expand 部分的末尾指定文件名,就在 | 字符之前)。
【讨论】:
您可以使用此正则表达式来获取前导空格或制表符
(^\s+)
但是用下划线替换它,我忍不住因为我没有 bash 经验
【讨论】: