Почему эта замена регулярных выражений не работает?

У меня есть файл в следующем формате:

$ cat myfile 12 42956 Cinema - 3D/Multiplex 7 12560 Status Update 5 184 Movie 

Я пытаюсь добавить двойные кавычки к текстовому описанию.
Я не могу понять, почему следующее регулярное выражение не работает:
$ sed -E 's/\b[0-9]+\b\s*\b[0-9]+\b\s*([^\s]+)/"\1"/g' myfile

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

  • Перемещение одного файла за раз, исходя из определенного числа в файлах
  • Редактирование вложенного текста и определенных строк в файле с использованием сценария bash
  • Различия между sed #,%, / и |
  • Как извлечь часть текста из файла?
  • Замена значений сущности XML положительным обратным знаком
  • заменить строку сложного текста в нескольких файлах
  • Добавление значения ко всем столбцам
  • извлечь url между 2 строками в файле
  • 3 Solutions collect form web for “Почему эта замена регулярных выражений не работает?”

    Насколько я знаю, \s является регулярным выражением Perl, которое совпадает с [[:blank:]] в sed . Внутри [ ... ] , \s означает «an \ и s ». Также обратите внимание, что даже если [^\s]+ было бы таким же, как [^␣]+ , это не соответствовало бы Status Update из-за пространства в середине.

    Замена заменит все совпадения первой группой в двойных кавычках. Вероятно, вы хотите поймать все три столбца, иначе вы получите только последний столбец. И поскольку вы пытаетесь сопоставить всю строку, вы должны привязать выражение в начале и конце с помощью ^ и $ и сбросить флаг g в конце.

    Альтернатива:

     $ sed -E 's/[[:alpha:]].+/"&"/' myfile 12 42956 "Cinema - 3D/Multiplex " 7 12560 "Status Update " 5 184 "Movie " 

    Это найдет последний столбец из-за того, что его данные всегда начинаются с цифры. Выражение просто будет соответствовать остальной части строки из первого алфавитного символа и заменить все совпадения на версию с двойными кавычками.

    Данные в вопросе имели пробелы в конце, и эти цитаты будут включать эти. Чтобы избежать пробелов в конце:

     $ sed -E -e 's/[[:blank:]]*$//' -e 's/[[:alpha:]].+/"&"/' myfile 12 42956 "Cinema - 3D/Multiplex" 7 12560 "Status Update" 5 184 "Movie" 

    С другой стороны,

     while read -rabc; do printf '%d\t%d\t"%s"\n' "$a" "$b" "$c"; done <myfile 12 42956 "Cinema - 3D/Multiplex" 7 12560 "Status Update" 5 184 "Movie" 
     sed -E 's/\b([0-9]+\b\s*\b[0-9]+)\b\s*([^\s]+)/\1 "\2"/g' myfile 

    Это добавляет двойные кавычки вокруг вашего текста.

    Сохраняя цифры и пробелы в группе \1 и строку в другой группе (\ 2), sed выводит группу 1 (\ 1), а затем пробел, за которым следует двойная кавычка, за которой следует вторая группа (\ 2), за которой следует окончательная двойная кавычка.

    Вы можете сократить это немного, объединив все цифры и пробелы в одной группе ([0-9, ]*) и все, что после цифр в другой группе (.+) .

    Это дает:

     sed -E 's/([0-9, ]*)(.+)/\1 "\2"/g' myfile 12 42956 "Cinema - 3D/Multiplex" 7 12560 "Status Update" 5 184 "Movie" 

    Поскольку Mac OSX sed не поддерживает \s . Только GNU sed поддерживает \s .

    В Mac OSX \s не работает, даже при цитировании $'' ANSI-C.

     $ echo $'1\t2 3' | sed 's/\s//g' 1 2 3 $ echo $'1\t2 3' | sed $'s/\s//g' 1 2 3 

    Вместо этого вы можете использовать [[:space:]]

     $ echo $'1\t2 3' | sed 's/[[:space:]]//g' 123 

    Или вы можете использовать [ \t] , но вам понадобится котировка $'' ANSI-C для символа табуляции.

     $ echo $'1\t2 3' | sed $'s/[ \t]//g' 123 
    Interesting Posts

    Redhat 7.1 Udev Изменяет правила SYMLINK + И Имя

    Не можете использовать! $ В скрипте?

    Правильная замена утилиты `logname`?

    В чем разница между патчем, который возвращает фиксацию и «обратный патч»?

    Автоматическая группировка / автоматическое табло Fluxbox: работает ли она больше?

    Как ядро ​​Linux сравнивается с микроядрами?

    Завершение вкладки busybox в режиме vi

    /etc/cron.daily/foo: отправить электронное письмо конкретному пользователю вместо root?

    Переименуйте файлы (удалите некоторые символы, которые не всегда одинаковы)

    Удалите частичные дубликаты последовательных строк, но сохраните первый и последний

    dpkg: error: дублировать запрос запуска файла для имени файла `/ usr / lib / gio / modules 'и пакета` libglib2.0-0'

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

    Как удалить только содержимое каталогов?

    Удалите все строки в файле A, содержащие строки в файле B

    сопоставить первый столбец файла a с параграфами файла b

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