如何从文件的每一行中去除前导空格

77

我有一个类似于下面的文件:

for (i = 0; i < 100; i++)
    for (i = 0; i < 100; i++)
  for (i = 0; i < 100; i++)
       for (i = 0; i < 100; i++)
     for (i = 0; i < 100; i++)
           for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)

我希望它看起来像这样(去除缩进):

for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)

如何实现这个功能(可能使用sed)?

8个回答

143
sed "s/^[ \t]*//" -i youfile

警告:这将覆盖原始文件。


3
值得一提的是,我无法在OS X Mavericks上使这个(或类似的)内容工作,而现在当我需要它时。然而,“perl -pe '<regexp>'”可以正常工作。我甚至尝试了向sed添加-E参数,但没有帮助。 - Per Lundberg
3
我可以证实,在OS X Mavericks上,与其它类Unix操作系统相比,sed命令存在缺陷。在字符类中似乎无法匹配任何转义字符。 - Chris Warth
4
你可以在OS X上安装gsed。 - Wei Qiu
8
在Mac OSX上,您可以使用ANSI-C引号$''来正确解释\t。必须使用单引号而不是双引号。sed $'s/^[ \t]*//'。此外,Mac OSX的sed不是GNU版本,因此不支持许多GNU特性。@per @chris - wisbucky
4
默认情况下,Mac 上的 sed 命令需要一个临时文件来进行内联替换。通常只需在 -i 后添加 '' 即可满足此要求。最终的命令是:sed -i '' 's/\s*//' yourfile - Ben
说句实话,你是我见过的第一个在正则表达式参数之后使用“-i”的程序员。这证明了我是人类中的昆虫,还是你是超人。坦白地说,我不确定是哪一个,但我觉得应该是后者。谢谢!谢谢!谢谢! - Jesse

32
针对这个特定问题,可以采用类似以下的解决方案:
$ sed 's/^ *//g' < input.txt > output.txt

它要求将行首的所有空格替换为空。如果你还想删除制表符,可以将其更改为:

$ sed 's/^[ \t]+//g' < input.txt > output.txt

在斜杠之前的“s”表示“替换”。 斜杆是模式的分隔符。 第一个和第二个斜杠之间的数据是要匹配的模式,而第二个和第三个斜杠之间的数据则是要替换模式的数据。 在这种情况下,您将其替换为无。 最后斜杠后面的“g”表示全局执行,即在整个文件上执行,而不仅限于找到的第一个匹配项。
最后,代替 < input.txt> output.txt ,您可以使用 -i 选项,该选项意味着“原地编辑”文件。 意思是,您不需要创建第二个文件来包含您的结果。 如果使用此选项,则会丢失原始文件。

不是直接的答案,但解决了我正在寻找的问题。谢谢! - Jesse

17

你可以使用AWK:

$ awk '{$1=$1}1' file
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)

sed

$ sed 's|^[[:blank:]]*||g' file
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)
for (i = 0; i < 100; i++)

使用 shell 的 while/read 循环

while read -r line
do
    echo $line
done <"file"

你的 sed 示例对我很有帮助,其他类似问题的答案都没有起作用。谢谢! - 2rs2ts
@ghostdog74 这种表达式([[:blank:]])叫什么?我看到另一个例子,人们使用[[:space:]]来删除前导空格。除了blank、space之外,还有哪些单词可以在这里使用?我只是想理解这个用法。谢谢! - olala
1
@olala 我在 tr 的 man 手册中找到了这个信息; [:blank:] 匹配所有水平空白字符,[:space:] 匹配所有水平或垂直空白字符。因此,如果您使用 [[:space:]],它不仅会删除空格和制表符,还会删除换行符 (\n),使您得到一行文本。使用 [[:blank:]] 将保留换行符。请注意,我尚未使用 sed 尝试过这个操作。 - user5359531
这是在我的MacOS上有效的命令。谢谢分享。 - Raymond

5
这段Perl代码可以编辑您的原始文件:
perl -i -ne 's/^\s+//;print' file

下一个功能是在编辑原始文件之前创建备份副本:
perl -i.bak -ne 's/^\s+//;print' file

请注意,Perl在很大程度上模仿了sed(和AWK)。

2

使用:

sed -e **'s/^[ \t]*//'**  name_of_file_from_which_you_want_to_remove_space > 'name _file_where_you_want_to_store_output'

例如:

举个例子:

sed -e 's/^[ \t]*//'  file1.txt > output.txt

注意:
s/:针对每个指定的行,在匹配的模式(^[ \t]*,^代表行首,[ \t]*匹配一个或多个空格,包括制表符)上进行替换操作。 ^[ \t]*:搜索模式(^代表行首;[ \t]*匹配一个或多个空格,包括制表符)。
//:替换(删除)所有匹配的模式。

1
您可以通过以下任何命令去除前导空格:
 - sed -i "s/\s*//" filename
 - sed -i "s/[[:space:]]*//"  filename        
 - sed -i "s/^\s*//"   filename
 - sed -i "s/[ \t]*//"  filename

如果您想删除空行,可以尝试以下任意一条命令:

 - sed "/^$/d"  filename

如果你想删除开头的任何空格、制表符或空行,可以使用以下命令:

sed  -i -e "/^$/d"   -i -e "s/^\s*//"  filename

0

这是你需要的:

user@host:~$ sed 's/^[\t ]*//g' < file-in.txt

或者:

user@host:~$ sed 's/^[\t ]*//g' < file-in.txt > file-out.txt

使用-i(原地)参数时,将只返回翻译后的文本。 - shuvalov

0

说句实话,如果你在编辑这个文件,你可能可以突出显示所有行,然后使用反制表符按钮。

  • 在 Vim 中,使用 Shift + V 来突出显示这些行,然后按下 <<
  • 如果你在 Mac 上,则可以使用 AtomSublime Text 等,然后用鼠标突出显示并按下 Shift + Tab

我不确定是否有一些要求必须从命令行完成。如果有的话,那么接受的答案就是 :thumbs-up:!=)


Prometheus,你在这里的评论是针对不同的答案吗? - Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接