Я должен заменить последнее слово от каждой строки с первой. Код:
$ sed "s/\(^a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\)/\1\2\1\g".
Я не понимаю эту часть \(^a-z,0-9]*\)\(.*\)\([a-z,0-9]*$\)
особенно \(.*\)
.
Я не думаю, что Ваш код даже собирается работать здесь, потому что это просто уродливо. Я переписал бы все выражение. При предположении, что все строки начинаются и заканчиваются словами, которые содержат только числа и буквы от алфавита, Вы могли попробовать это:
$ 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
- та же строка с последним словом, замененным первым.
После исправления ошибок базового синтаксиса Вы имеете:
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
используйте ДО (сохраняет использование всех тех обратных косых черт),[^ ]+
по крайней мере один из любых символов кроме пробелов