rub*_*o77 265 pipe shell-script text-processing whitespace
我想从输出的每一行中删除所有前导和尾随空格和制表符。
有没有一个简单的工具,比如trim我可以将我的输出输入到其中?
示例文件:
test space at back
test space at front
TAB at end
TAB at front
sequence of some space in the middle
some empty lines with differing TABS and spaces:
test space at both ends
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 337
awk '{$1=$1;print}'
Run Code Online (Sandbox Code Playgroud)
或更短:
awk '{$1=$1};1'
Run Code Online (Sandbox Code Playgroud)
将修剪前导和尾随空格或制表符1 并将制表符和空格序列压缩到一个空格中。
这是有效的,因为当您为其中一个字段分配某些内容时,通过将所有字段 ( , ..., ) 与(默认情况下为空格) 连接起来,awk重建整个记录(如 打印的那样)。print$1$NFOFS
也删除空行,将其更改为awk '{$1=$1};NF'(其中NF讲述awk仅打印记录其中N的赭Fields不为零)。千万不能这样做,因为有时候建议作为,这也将删除线,其第一场是任何陈述awk '$1=$1'0所支持awk(0,00,-0e+12...)
1(可能还有其他空白字符,具体取决于语言环境和awk实现)
slm*_*slm 81
如果您使用的是 GNU,则可以像这样压缩命令sed:
$ sed 's/^[ \t]*//;s/[ \t]*$//' < file
Run Code Online (Sandbox Code Playgroud)
这是上面的命令在起作用。
$ echo -e " \t blahblah \t " | sed 's/^[ \t]*//;s/[ \t]*$//'
blahblah
Run Code Online (Sandbox Code Playgroud)
您可以使用hexdump来确认该sed命令是否正确地剥离了所需的字符。
$ echo -e " \t blahblah \t " | sed 's/^[ \t]*//;s/[ \t]*$//' | hexdump -C
00000000 62 6c 61 68 62 6c 61 68 0a |blahblah.|
00000009
Run Code Online (Sandbox Code Playgroud)
您还可以使用字符类名称而不是像这样逐字列出集合,[ \t]:
$ sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//' < file
Run Code Online (Sandbox Code Playgroud)
$ echo -e " \t blahblah \t " | sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//'
Run Code Online (Sandbox Code Playgroud)
大多数使用正则表达式 (regex) 的 GNU 工具都支持这些类(这里有它们在基于 ASCII 的系统的典型 C 语言环境中的等效项(并且仅在那里))。
[[:alnum:]] - [A-Za-z0-9] Alphanumeric characters
[[:alpha:]] - [A-Za-z] Alphabetic characters
[[:blank:]] - [ \t] Space or tab characters only
[[:cntrl:]] - [\x00-\x1F\x7F] Control characters
[[:digit:]] - [0-9] Numeric characters
[[:graph:]] - [!-~] Printable and visible characters
[[:lower:]] - [a-z] Lower-case alphabetic characters
[[:print:]] - [ -~] Printable (non-Control) characters
[[:punct:]] - [!-/:-@[-`{-~] Punctuation characters
[[:space:]] - [ \t\v\f\n\r] All whitespace chars
[[:upper:]] - [A-Z] Upper-case alphabetic characters
[[:xdigit:]] - [0-9a-fA-F] Hexadecimal digit characters
Run Code Online (Sandbox Code Playgroud)
使用这些而不是文字集似乎总是浪费空间,但是如果您担心代码的可移植性,或者必须处理替代字符集(考虑国际化),那么您可能想要使用类名反而。
小智 41
没有参数的 xargs 做到这一点。
例子:
trimmed_string=$(echo "no_trimmed_string" | xargs)
Run Code Online (Sandbox Code Playgroud)
rub*_*o77 31
正如Stéphane Chazelas在接受的答案中所建议的,您现在可以
创建一个脚本/usr/local/bin/trim:
#!/bin/bash
awk '{$1=$1};1'
Run Code Online (Sandbox Code Playgroud)
并赋予该文件可执行权限:
chmod +x /usr/local/bin/trim
Run Code Online (Sandbox Code Playgroud)
现在您可以将每个输出传递trim给例如:
cat file | trim
Run Code Online (Sandbox Code Playgroud)
(对于下面的评论:我以前使用过这个:while read i; do echo "$i"; done
它也可以正常工作,但性能较差)
Łuk*_*hel 24
如果将行存储为变量,则可以使用 bash 来完成这项工作:
shopt -s extglob
printf '%s\n' "${text##+([[:space:]])}"
Run Code Online (Sandbox Code Playgroud)
shopt -s extglob
printf '%s\n' "${text%%+([[:space:]])}"
Run Code Online (Sandbox Code Playgroud)
printf '%s\n' "${text//[[:space:]]}"
Run Code Online (Sandbox Code Playgroud)
小智 22
由于“管道”工具,为了从给定行中删除所有前导和尾随空格,我可以确定 3 种不完全等效的不同方式。这些差异涉及输入行单词之间的空格。根据预期的行为,您将做出选择。
为了解释差异,让我们考虑这个虚拟输入行:
" \t A \tB\tC \t "
Run Code Online (Sandbox Code Playgroud)
$ echo -e " \t A \tB\tC \t " | tr -d "[:blank:]"
ABC
Run Code Online (Sandbox Code Playgroud)
tr真的是一个简单的命令。在这种情况下,它会删除任何空格或制表符。
$ echo -e " \t A \tB\tC \t " | awk '{$1=$1};1'
A B C
Run Code Online (Sandbox Code Playgroud)
awk 删除前导和尾随空格,并将单词之间的每个空格压缩到一个空格。
$ echo -e " \t A \tB\tC \t " | sed 's/^[ \t]*//;s/[ \t]*$//'
A B C
Run Code Online (Sandbox Code Playgroud)
在这种情况下,sed删除前导和尾随空格而不触及单词之间的任何空格。
评论:
在每行一个单词的情况下,tr完成这项工作。
Gil*_*il' 19
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
Run Code Online (Sandbox Code Playgroud)
如果您正在将一行读入 shell 变量,除非另有说明,否则read已经这样做了。
qwr*_*qwr 10
一个你一看就明白的答案:
#!/usr/bin/env python3
import sys
for line in sys.stdin: print(line.strip())
Run Code Online (Sandbox Code Playgroud)
奖励:str.strip([chars])用任意字符替换以修剪或使用.lstrip()或.rstrip()根据需要。
就像rubo77 的答案一样,另存为脚本/usr/local/bin/trim并授予权限chmod +x。
您将把它添加到您的小 Bash 库中。我几乎可以打赌!这样做的好处是不会在输出末尾添加换行符echo,就像丢弃预期输出一样。此外,这些解决方案是可重用的,不需要修改 shell 选项,可以与管道内联调用,并且符合 posix 标准。这是迄今为止最好的答案。根据您的喜好进行修改。
使用 测试输出od -cb,其他一些解决方案可能希望对其输出执行某些操作。
顺便说一句:正确的量词是+,而不是*,因为您希望在 1 个或多个空白字符上触发替换!
function ltrim ()
{
sed -E 's/^[[:space:]]+//'
}
Run Code Online (Sandbox Code Playgroud)
function rtrim ()
{
sed -E 's/[[:space:]]+$//'
}
Run Code Online (Sandbox Code Playgroud)
function trim ()
{
ltrim | rtrim
}
Run Code Online (Sandbox Code Playgroud)
sed 是一个很好的工具:
# substitute ("s/")
sed 's/^[[:blank:]]*//; # parts of lines that start ("^") with a space/tab
s/[[:blank:]]*$//' # or end ("$") with a space/tab
# with nothing (/)
Run Code Online (Sandbox Code Playgroud)
您可以将它用于您的案例,或者在文本中使用管道,例如
<file sed -e 's/^[[...
Run Code Online (Sandbox Code Playgroud)
或者,如果您sed是 GNU 用户,则通过“内联”对其进行操作:
sed -i 's/...' file
Run Code Online (Sandbox Code Playgroud)
但是以这种方式更改源是“危险的”,因为当它不能正常工作时(甚至当它正常工作时)它可能无法恢复,所以首先备份(或使用-i.bak它也有利于移植到某些 BSD seds) !