如何使用 sed 将多个空格去除为一个?

如何使用 sed 将多个空格去除为一个?

sedAIX 上没有做我认为应该做的事情。我试图在 IOSTAT 的输出中用单个空格替换多个空格:

# iostat
System configuration: lcpu=4 drives=8 paths=2 vdisks=0

tty:      tin         tout    avg-cpu: % user % sys % idle % iowait
          0.2         31.8                9.7   4.9   82.9      2.5

Disks:        % tm_act     Kbps      tps    Kb_read   Kb_wrtn
hdisk9           0.2      54.2       1.1   1073456960  436765896
hdisk7           0.2      54.1       1.1   1070600212  435678280
hdisk8           0.0       0.0       0.0          0         0
hdisk6           0.0       0.0       0.0          0         0
hdisk1           0.1       6.3       0.5   63344916  112429672
hdisk0           0.1       5.0       0.2   40967838  98574444
cd0              0.0       0.0       0.0          0         0
hdiskpower1      0.2     108.3       2.3   2144057172  872444176

# iostat | grep hdisk1
hdisk1           0.1       6.3       0.5   63345700  112431123

#iostat|grep "hdisk1"|sed -e"s/[ ]*/ /g"
 h d i s k 1 0 . 1 6 . 3 0 . 5 6 3 3 4 5 8 8 0 1 1 2 4 3 2 3 5 4

sed 应该为整个组 (/g) 搜索并用单个空格 (/ /) 替换多个空格 (/[ ]*/)...但它不仅这样做...它的每个字符的间距。

我究竟做错了什么?我知道它一定很简单... AIX 5300-06

编辑:我有另一台有 10 多个硬盘的计算机。我将其用作另一个程序的参数以进行监控。

我遇到的问题是“awk '{print $5}' 不起作用,因为我在第二阶段使用 $1 等,并在 Print 命令中出现错误。我正在寻找 grep/sed/cut 版本似乎有效的是:

iostat | grep "hdisk1 " | sed -e's/  */ /g' | cut -d" " -f 5

当我认为 [] 的意思是“只有一个”时,它们是“0 或更多”。拆掉支架就可以工作了。三个非常好的答案很快就让人很难选择“答案”。

答案1

/[ ]*/火柴或更多空格,因此字符之间的空字符串匹配。

如果您尝试匹配“一个或多个空格”,请使用以下之一:

... | sed 's/  */ /g'
... | sed 's/ \{1,\}/ /g'
... | tr -s ' '

答案2

使用grep是多余的,sed可以做同样的事情。问题在于使用*它也匹配0个空格。对于 GNU sed,您可以使用\+

iostat | sed -n '/hdisk1/s/ \+/ /gp'

或者,使用标准sed

iostat | sed -e '/hdisk/!d' -e 's/ \{2,\}/ /g'

删除所有不包含子字符串 的行hdisk,并将所有两个或多个空格替换为单个空格,或者

iostat | sed -e '/hdisk1/!d' -e 's/   */ /g'

答案3

将您的*运算符更改为+.您正在匹配零个或多个前一个字符,它匹配每个字符,因为所有不是空格的内容都是......嗯......零个空格实例。您需要匹配一个或多个。实际上,匹配两个或多个会更好

括号内的字符类对于匹配一个字符来说也是不必要的。你可以只使用:

s/  \+/ /g

...除非您也想匹配制表符或其他类型的空格,否则字符类是一个好主意。

答案4

请注意,您也可以做您尝试的事情,即

iostat | grep "hdisk1 " | sed -e's/  */ /g' | cut -d" " -f 5

经过

iostat | while read disk tma kbps tps re wr; do [ "$disk" = "hdisk1" ] && echo "$re"; done

如果您稍后尝试访问其他字段和/或计算某些内容,这可能特别有用 - 像这样:

iostat | while read disk tma kbps tps re wr; do [ "$disk" = "hdisk1" ] && echo "$(( re/1024 )) Mb"; done

相关内容