Понимание sed выражение для замены последнего слова от каждой строки с первой

Я должен заменить последнее слово от каждой строки с первой. Код:

$ sed "s/\(^a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\)/\1\2\1\g". 

Я не понимаю эту часть \(^a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\) особенно \(.*\).

4
задан 26 March 2017 в 15:29

2 ответа

Я не думаю, что Ваш код даже собирается работать здесь, потому что это просто уродливо. Я переписал бы все выражение. При предположении, что все строки начинаются и заканчиваются словами, которые содержат только числа и буквы от алфавита, Вы могли попробовать это:

$ echo -en "foo bar baz\nThe Good, the Bad and the Ugly\n" | \
> sed 's/^\(\<[[:alpha:]]\+\>\)\(.*\)\<[[:alpha:]]\+\>$/\1\2\1/g'
foo bar foo
The Good, the Bad and the The

Краткое объяснение:

s/PATTERN/SUBSTITUTION_STRING/g - ШАБЛОН - то, что мы ищем, и SUBSTITUTION_STRING - то, чем мы собираемся заменить, сказал что шаблон с. g средства, что вся строка будет просканирована в противоположность движению только для первого соответствия, найденного на строке.

^\(\<[[:alpha:]]\+\>\) - если строка начинается с границы слова, это сопровождается больше чем одним буквенно-цифровым знаком, сопровождаемым другой границей слова, сохраните все это в переменной \1.

\<[[:alpha:]]\+\>$ - та же точная вещь здесь, но мы только используем это для идентификации местоположения последнего слова.

\(.*\) - что-либо промежуточное будет сохранено в переменной \2.

\1\2\1 - та же строка с последним словом, замененным первым.

3
ответ дан 23 November 2019 в 11:39

После исправления ошибок базового синтаксиса Вы имеете:

sed "s/\(^[a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\)/\1\2\1/g"
  • s/old/new/ замена old с new
  • \(^[a-z,0-9]*\) сохраните любое количество строчных букв или чисел в начале строки (^ запуск строки) на потом (ссылка позже с \1)
  • \(.*\) Сохраните любое количество любых символов на потом (к ссылке как \2)
  • \([a-z,0-9]*$\) сохраните любое количество строчных букв или чисел в конце строки ($ конец строки) на потом (ссылка как \3)
  • \1\2\1 распечатайте первый шаблон, затем второе, затем первое снова
  • g это является несоответствующим в этом выражении. Это означает действие на нескольких соответствиях на той же строке, но наше выражение должно считать целую строку, таким образом, g не имеет никакого смысла и должен быть опущен.

Это все еще не будет работать, потому что регулярные выражения являются жадными, таким образом, середина \(.*\) соответствия все после первого слова, приводящего к первому слову, переиздаваемому в конце строки, ничего не заменяя.

Вы могли зафиксировать его (также добавление I для поиска без учета регистра):

sed "s/\(^[a-z,0-9]*\) \(.*\) \([a-z,0-9]*$\)/\1 \2 \1/I"

Если Вы хотели включать другие символы помимо букв и чисел:

sed -r 's/^([^ ]+) (.*) ([^ ]+)$/\1 \2 \1/'
  • -r используйте ДО (сохраняет использование всех тех обратных косых черт),
  • [^ ]+ по крайней мере один из любых символов кроме пробелов
10
ответ дан 23 November 2019 в 11:39

Другие вопросы по тегам:

Похожие вопросы: