Как разбить несколько пробелов на один с помощью sed?

sed на AIX не делает то, что я думаю, что нужно. Я пытаюсь заменить несколько пробелов на единое пространство на выходе 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" hdisk 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 или более», когда я думал, что они означают «только один». Снятие скобок заставило его работать. Три очень хорошие ответы действительно быстро затрудняют выбор «ответа».

  • Удалите x строк до и y строк после n-й строки (которая соответствует шаблону) в файле
  • Regex не соответствует
  • Только кошка из определенной строки X (с рисунком) в другую определенную строку Y (с рисунком)
  • Заменить значения в определенном разделе в файле
  • Поиск и удаление специального символа
  • Печатать текст между (и включая) двумя разделителями по строке
  • Изменить заголовок с помощью sed или awk
  • Выполните команду в 'sed'
  • 6 Solutions collect form web for “Как разбить несколько пробелов на один с помощью sed?”

    Использование grep избыточно, sed может сделать то же самое. Проблема заключается в использовании * которое соответствует также 0 пробелам, вы должны использовать \+ вместо:

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

    Если ваш sed не поддерживает \+ metachar, тогда сделайте

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

    /[ ]*/ соответствует нулю или больше пробелов, поэтому пустая строка между символами совпадает.

    Если вы пытаетесь сопоставить «одно или несколько пробелов», используйте один из следующих:

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

    Измените оператора * на + . Вы сопоставляете ноль или более предыдущего символа, который соответствует каждому символу, потому что все, что не является пространством, это … um … нулевые экземпляры пространства. Вы должны соответствовать ОДИН или больше. На самом деле было бы лучше совместить два или более

    Класс символов в квадратных скобках также не нужен для сопоставления одного символа. Вы можете просто использовать:

     s/ \+/ /g 

    … если вы также не хотите сопоставлять вкладки или другие типы пространств, тогда класс символов является хорошей идеей.

    Обратите внимание, что вы также можете делать то, что вы пытаетесь сделать,

     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 

    Вы всегда можете совместить последнее вхождение в последовательности чего-либо типа:

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

    И поэтому вы на правильном пути, но вместо того, чтобы заменять последовательность пространством, замените его своим последним вложением – одним пробелом. Таким образом, если последовательность пробелов согласована, последовательность сводится к одному пространству, но если нулевая строка сопоставляется, то нулевая строка заменяется на себя – и никакого вреда не бывает. Так, например:

     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 

    ВЫВОД

     # 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 

    Все сказанное, вероятно, гораздо лучше избегать регулярных выражений в этой ситуации и вместо этого:

     tr -s \ <infile 

    Вы можете использовать следующий скрипт для преобразования нескольких пространств в одно пространство, TAB или любую другую строку:

     $ 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" 
    Interesting Posts

    Ubuntu Server 16.04.3LTS Squashfs как root из Grub

    Создание пакета Debian, который не удаляет каталоги после его очистки

    Может ли параметр BS вызывать несогласованность данных с dd?

    Как запретить доступ к определенному порту, когда пункт назначения НЕ является конкретным хостом?

    Удаление определенных символов из нескольких файлов с помощью белых кликов

    Если UID = 1000 продолжается, иначе выйдите

    Почему так мало «запущенных» процессов?

    Как я могу совместно использовать внутренний диск через NFS? (Что я делаю не так?)

    Как увеличить окно по горизонтали или по вертикали?

    Условные зависимости для пакета Debian

    Можно ли запустить FreeRDP без отображения для запуска скриптов?

    Как установить Apache Tomcat 8 на centos 7?

    Неизвестный TCP в выводе nethogs

    Используйте только left alt в качестве модификатора в i3wm?

    Как скопировать текст из командной строки в буфер обмена без использования мыши?

    Linux и Unix - лучшая ОС в мире.