Это было сложно. Предположим, что у вас есть файл
следующего вида:
$ cat file
word
line with a word and words and wording wordy words.
Где:
`word`
. Команда sed
:
sed -n '1h; 2{x;G;:l;s/^\([^\n]\+\)\n\(.*[^`]\)\1\([^`]\)/\1\n\2`\1`\3/;tl;p}' file
Explanation:
1h;
сохраняет первую строку в hold space (это ожидание, которое мы хотим искать).
word
2{...}
применяется ко второй строке. x;
обменивает пространство шаблона и пространство удержания. G;
добавляем пространство удержания к пространству шаблона. Теперь в пространстве шаблонов мы имеем: word # I will call this line the "pattern line" from now on
line with a word and words and wording wordy words.
:l;
устанавливаем метку l
как точку для последующего использования. s///
выполняем фактический поиск/замену в пространстве шаблонов, упомянутом выше:
^\([^\n]\+\)\n
поиск в "строке шаблона" всех символов (с начала строки ^
), которые не являются новой строкой [^\n]
(один или несколько раз \+
), до новой строки \n
. Теперь она сохраняется в обратной ссылке \1
. Она содержит "шаблонную строку". (.*[^`])
поиск любого символа .*
, за которым следует символ, не являющийся обратным знаком [^`]
. Это хранится в \2
. \2
теперь содержит: строка со словом и слова и формулировки словесные
, до последнего появления слова
, потому что... \1
является следующим поисковым термином (обратная ссылка \1
, слово
), отсюда следует, что "шаблонная строка" содержит. ([^`])
за этим следует другой символ, который не является обратным знаком; сохраняется для ссылки \3
. Если мы не сделаем этого (и часть в \2
сверху), мы окажемся в бесконечном цикле, цитируя одно и то же слово
, снова и снова -> ````word````
, потому что s///
всегда будет успешным и tl;
перепрыгнет обратно к : l
(см. tl;
далее). \1\n\2\1
\3
все вышеперечисленное заменяется обратными ссылками. Второе \1
- это то, что мы должны процитировать (обратите внимание, что первая ссылка - это "шаблонная строка"). tl;
если s///
был успешным (мы что-то заменили), переходим к метке l
и начинаем снова, пока больше нечего искать и заменять. Это происходит, когда заменяются/цитируются все вхождения слова. p;
когда все будет сделано, выведите измененную строку (пробел в шаблоне). The output:
$ sed -n '1h; 2{x;G;:l;s/^\([^\n]\+\)\n\(.*[^`]\)\1\([^`]\)/\1\n\2`\1`\3/;tl;p}' file
word
line with a `word` and `word`s and `word`ing `word`y `word`s.