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

У меня есть следующий список предметов:

bigBone fishMarket dogCollar ... 

Мне нужно создать двухсимвольное отображение следующим образом:

 bigBone -> bb fishMarket -> fm dogCollar -> dc ... 

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

Я пробовал что-то вроде:

 sed -i -r 's/^([az]{1})[az]+([AZ]{1})[a-zA-Z]+/ -> \1\L\2/' file 

Я видел этот вопрос , но не уверен, как включить здесь концепцию. Благодарю.

6 Solutions collect form web for “Как выполнять поиск, замену и добавление шаблона в конец каждой строки”

Если я правильно вас понимаю, вы хотите сохранить всю строку и просто добавить что-то:

 sed -r 's/^([az]{1})([az]+)([AZ]{1})([a-zA-Z]+)$/\1\2\3\4 -> \1\L\3/' file 

Редактировать :

devnull должен был напомнить мне об этом, что есть легкое решение этого:

 sed -r 's/^([az]{1})[az]+([AZ]{1})[a-zA-Z]+/& -> \1\L\2/' file 

Или, немного более элегантно (чем моя первая попытка):

 sed -r ' h s/^([az]{1})[az]+([AZ]{1})[a-zA-Z]+/ -> \1\L\2/ t append b : append H g s/\n//' file 

Использование GNU sed:

 sed -r 's/(.)[^[:upper:]]*(.).*/& -> \1\L\2/' inputfile 

Для вашего ввода это произвело бы:

 bigBone -> bb fishMarket -> fm dogCollar -> dc 

Чтобы обобщить на fooBarBaz -> fbb , abCdEfGh -> aceg , с помощью GNU sed :

 sed -r 's/(.)(.*)/\1\n\2 -> \L\1/;:1 s/\n([^[:upper:]]*([[:upper:]]))(.*)/\1\n\3\L\2/;t1;s/\n//' 

У POSIX sed нет \L Таким образом, переносимо, вам придется прибегнуть к использованию y и вручную ввести все символы, которые вы хотите преобразовать в нижний регистр. Что-то вроде:

 LC_ALL=C sed '/^\([[:alpha:]]\).*/{ h;s//\1/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;G s/\(.\).\(.\)\(.*\)/\2\ \3 -> \1/;:1 /.*\n[^AZ]*\([AZ]\).*/{h;s//\1/ y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;G s/^\(.\)\n\(.*\)\n\([^AZ]*[AZ]\)\(.*\)/\2\3\ \4\1/;t1 } s/\n//;}' 

Вот он с POSIX-совместимым скриптом. Я не знал, что POSIX sed оставляет поведение s///[n]g неуказанным, но, конечно же , это не четкое поведение. Во всяком случае, без него легко справиться – я просто не люблю использовать слишком много обратных ссылок, если это может быть полезно, как правило.

 sed '/^[az]*[AZ].*$/{ h s/\(.\)[^AZ]*/\1/g y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ H ; gs/\n/ -> / }' <<\DATA bigBone fishMarket dogCollar DATA #OUTPUT bigBone -> bb fishMarket -> fm dogCollar -> dc 

Этот ответ похож на @ devnull's,

 $ sed 's/\(.\).*\([AZ]\).*/& -> \1\L\2/g' file bigBone -> bb fishMarket -> fm dogCollar -> dc 

Если вы можете использовать perl , попробуйте:

 $ perl -MList::Util=first -F// -aple '$_ .= " -> ".$F[0].lc(first{ord() < 97} @F)' file bigBone -> bb fishMarket -> fm dogCollar -> dc 
  • pcregrep не работает из-за ошибки сегментации
  • Комментируйте разделы текста, соответствующие определенным идентификаторам, перечисленным в другом файле
  • Как удалить строки в файле с определенной позиции до конца файла
  • Как удалить идентичные строки в одном файле из другого, используя sed?
  • Как получить второе имя каталога в пути к файлу perforce?
  • Нечувствительность к регистру, дублирующая строку, удалите дубликат по выбору случая с самым высоким дублированием
  • Различия между sed на Mac OSX и другим «стандартным» sed?
  • Как настроить интервал между символами после определенной строки?
  • Заменить текст с помощью sed и сохранить часть исходного текста
  • Какая версия sed не является GNU sed 4.0?
  • Заменить шаблон, если перед вторым шаблоном - сохранить строку между двумя
  • как удалить строку из файла XML
  • Linux и Unix - лучшая ОС в мире.