如何去除字符串开头和结尾的空格?

15
我正在使用awk '{gsub(/^[ \t]+|[ \t]+$/,""); print;}' in.txt > out.txt来去除前导和尾随的空格。
问题是输出文件实际上有尾随的空格!所有行的长度都相同 - 它们右侧用空格填充。
我错过了什么?
更新1
问题可能是由于尾随空格不是“正常”空格而是\x20字符(DC4)引起的。
更新2
我使用了gsub (/'[[:cntrl:]]|[[:space:]]|\x20/,""),它起作用了。 两件奇怪的事情:
1.为什么\x20不被视为控制字符?
2.使用'[[:cntrl:][:space:]\x20不起作用。为什么?

更新:也许这些不是简单的空格,而是DC4控制字符?这些文件起源于Windows。 - user1194552
1
\x20 是普通的 ASCII 空格。控制字符是 \x00\x1F - tripleee
4个回答

26

这个命令对我有效:

$ awk '{$1=$1}1' file.txt

+1,为什么不呢?;-) 你甚至可以这样做:awk '$1=$1' file.txt,是吧? - oHo
3
@eddi,awk将通过删除额外的空格来规范化一行。 $1=$1触发了该操作,否则什么也不会发生。 - kev
1
我认为你应该将其添加到答案中,并解释一下1的作用。 - eddi
2
@eddi 中的 1{print} 相同,它将打印每一行。 - kev
1
@kev:在CentOS 6.5上,使用GNU Awk 3.1.7和ksh无法正常工作:echo "foo;bar ">tt && print "_$( awk -F";" -OFS";" '{$2=$2}1' tt)_"输出为_foo;bar _。我错过了什么吗?顺便问一下,你的设置是什么? - Mat M
显示剩余2条评论

5

你的代码对我来说没问题。
可能有其他字符而不是 空格制表符 ...
hexdump -C 可以帮助您检查出错的地方:

awk '{gsub(/^[ \t]+|[ \t]+$/,""); print;}' in.txt | hexdump -C | less

更新:

好的,你已经确认了DC4(可能还有其他控制字符...)
那么,你可以改进你的命令:

awk '{gsub(/^[[:cntrl:][:space:]]+|[[:cntrl:][:space:]]+$/,""); print;}' in.txt > out.txt

请参阅 awk 说明文档:

[:alnum:] 表示字母数字字符。
[:alpha:] 表示字母字符。
[:blank:] 表示空格或制表符字符。
[:cntrl:] 表示控制字符。
[:digit:] 表示数字字符。
[:graph:] 表示既可打印又可见的字符。 (空格是可打印但不可见的,而 a 两者都具备。)
[:lower:] 表示小写字母字符。
[:print:] 表示可打印字符(即非控制字符)。
[:punct:] 表示标点符号字符(即既不是字母、数字、控制字符也不是空格字符的符号)。
[:space:] 表示空白字符(例如空格、制表符和换页符等)。
[:upper:] 表示大写字母字符。
[:xdigit:] 表示十六进制数字字符。

去除前导/尾随的 0x20

对我来说,这个命令是可以的,我已经进行了测试,就像这样:

$ echo -e "\x20 \tTEXT\x20 \t" | hexdump -C
00000000  20 20 09 54 45 58 54 20  20 09 0a                 |  .TEXT  ..|
0000000b
$ echo -e "\x20 \tTEXT\x20 \t" | awk '{gsub(/^[[:cntrl:][:space:]]+|[[:cntrl:][:space:]]+$/,""); print;}' | hexdump -C
00000000  54 45 58 54 0a                                    |TEXT.|
00000005

然而,如果你的文本中间有 0x20
=> 那么它就不会被移除。
但这不是你的问题,对吧?


我真的以为这会起作用,但是它并没有,我仍然有所有这些“空格”ASCII代码20(int = 32)。 - user1194552
1
你好@user1194552。请在进行awk处理前后提供您的hexdump -C输出,这样我就能更好地理解您的问题。因为在我的测试中,看起来是正常的 :-) - oHo
你的 awk --version 是什么?我可以测试两个版本:GNU Awk 3.1.3GNU Awk 3.1.5。请提供你的 hexdump -C。然后我就可以和你做同样的测试了。 - oHo

1

你的文件可能有Windows行尾。这意味着它们以\r\n结尾,因此匹配行末的制表符和空格序列将不起作用--awk尝试匹配在\r之后出现的所有制表符和空格。在将文件发送到awk之前,尝试通过tr -d "\r"运行文件。


0

Perl 可以使用:

perl -lpe 's/^\s*(.*\S)\s*$/$1/' in.txt > out.txt

s/foo/bar/ 使用正则表达式进行替换
^ 字符串开头
\s* 零个或多个空格
(.*\S) 任何以非空白字符结尾的字符。将其捕获到 $1 中
\s* 零个或多个空格
$ 字符串结尾


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