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개 이상의 하드 드라이브가 있는 컴퓨터가 하나 더 있습니다. 모니터링을 위해 다른 프로그램의 매개변수로 사용하고 있습니다.

내가 겪고 있는 문제는 두 번째 단계에서 $1 등을 사용하고 인쇄 명령에 오류가 발생하기 때문에 "awk '{print $5}'가 작동하지 않는다는 것입니다. grep/sed/cut 버전은 ' m 찾고 있는 것은 작동하는 것 같습니다:

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

*연산자를 로 변경하세요 +. 0개 이상의 이전 문자와 일치합니다. 공백이 아닌 모든 문자는...글쎄...공백이 0이므로 모든 문자와 일치합니다. 하나 이상 일치해야 합니다. 사실 2개 이상 매칭하는 게 더 나을 것 같아요

괄호로 묶인 문자 클래스도 문자 일치에 필요하지 않습니다. 다음을 사용할 수 있습니다.

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

관련 정보