it-swarm-id.com

Bagaimana cara menghapus beberapa spasi menjadi satu menggunakan sed?

sed pada AIX tidak melakukan apa yang saya pikir seharusnya. Saya mencoba mengganti beberapa ruang dengan satu ruang dalam output 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 harus mencari & mengganti beberapa spasi (/ [] * /) dengan satu spasi (/ /) untuk seluruh grup (/ g) ... tapi itu tidak hanya melakukan itu ... mengatur jarak setiap karakter.

Apa yang saya lakukan salah? Saya tahu ini pasti sesuatu yang sederhana ... AIX 5300-06

edit: Saya memiliki komputer lain yang memiliki 10+ hard drive. Saya menggunakan ini sebagai parameter ke program lain untuk tujuan pemantauan.

Masalah yang saya temui adalah "awk '{print $ 5}' tidak berfungsi karena saya menggunakan $ 1, dll pada tahap sekunder dan memberikan kesalahan dengan perintah Print. Saya mencari versi grep/sed/cut Apa yang tampaknya berhasil adalah:

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

[] Adalah "0 atau lebih" ketika saya pikir artinya "hanya satu". Menghapus braket membuatnya berfungsi. Tiga jawaban yang sangat baik sangat cepat membuat sulit untuk memilih "jawaban".

72
WernerCD

Penggunaan grep berlebihan, sed dapat melakukan hal yang sama. Masalahnya adalah dalam penggunaan * yang cocok dengan 0 spasi, Anda harus menggunakan \+ sebagai gantinya:

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

Jika sed Anda tidak mendukung \+ metachar, lalu lakukan

iostat | sed -n '/hdisk1/s/  */ /gp'
57
enzotib

/[ ]*/ cocok nol atau lebih banyak spasi, jadi string kosong antar karakter cocok.

Jika Anda mencoba mencocokkan "satu atau lebih spasi", gunakan salah satu dari ini:

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

Ubah-Mu * operator ke +. Anda mencocokkan nol atau lebih dari karakter sebelumnya, yang cocok dengan setiap karakter karena semua yang bukan spasi adalah ... um ... nol contoh spasi. Anda harus mencocokkan SATU atau lebih. Sebenarnya akan lebih baik untuk mencocokkan dua atau lebih

Kelas karakter yang dikurung juga tidak perlu untuk mencocokkan satu karakter. Anda bisa menggunakan:

s/  \+/ /g

... kecuali jika Anda ingin mencocokkan tab atau jenis ruang lainnya juga, maka kelas karakter adalah ide yang bagus.

15
Caleb

Anda selalu dapat mencocokkan kejadian terakhir dalam urutan yang seperti:

s/\(sequence\)*/\1/

Jadi Anda berada di jalur yang benar, tetapi alih-alih mengganti urutan dengan spasi - ganti dengan kejadian terakhir - satu ruang. Dengan cara itu jika urutan spasi is cocok maka urutan dikurangi menjadi satu ruang, tetapi jika string nol dicocokkan maka string nol diganti dengan dirinya sendiri - dan tidak ada salahnya, tidak ada salahnya, tidak ada pelanggaran. Jadi, misalnya:

sed 's/\( \)*/\1/g' <<\IN                                    
# 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

IN

KELUARAN

# 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

Semua yang dikatakan, mungkin jauh lebih baik untuk menghindari regexps sepenuhnya dalam situasi ini dan lakukan sebaliknya:

tr -s \  <infile
8
mikeserv

Perhatikan bahwa Anda juga dapat melakukan apa yang Anda usahakan, yaitu

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

oleh

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

yang mungkin sangat berguna jika nanti Anda mencoba mengakses bidang lain juga dan/atau menghitung sesuatu - seperti ini:

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

Anda dapat menggunakan skrip berikut untuk mengonversi beberapa spasi menjadi satu spasi, TAB atau string lain:

$ ls | compress_spaces.sh       # converts multiple spaces to one
$ ls | compress_spaces.sh TAB   # converts multiple spaces to a single tab character
$ ls | compress_spaces.sh TEST  # converts multiple spaces to the phrase TEST
$ compress_spaces.sh help       # show the help for this command

compress_spaces.sh

function show_help()
{
  IT=$(CAT <<EOF

  usage: {REPLACE_WITH}

  NOTE: If you pass in TAB, then multiple spaces are replaced with a TAB character

  no args -> multiple spaces replaced with a single space
  TAB     -> multiple spaces replaced with a single tab character
  TEST    -> multiple spaces replaced with the phrase "TEST"

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi

# Show help if we're not getting data from stdin
if [ -t 0 ]; then
  show_help
fi

REPLACE_WITH=${1:-' '}

if [ "$REPLACE_WITH" == "tab" ]
then
  REPLACE_WITH=$'\t'
fi
if [ "$REPLACE_WITH" == "TAB" ]
then
  REPLACE_WITH=$'\t'
fi

sed "s/ \{1,\}/$REPLACE_WITH/gp"
0
Brad Parks