Не уверен, что это именно то, что вам нужно, поскольку ваш вопрос довольно неточный, но он может дать вам представление.Конечно, это решение не то, что вы должны использовать (используйте awk
).
Строки uuid1
и uuid2
могут быть заменены любыми двумя строками, которых еще нет в файле.
sed -E -e 'H;1h;$!d;x' \
-e 's/four/uuid1/' -e 's/four/uuid1/' -e 's/four/uuid1/' \
-e 's/eight/uuid2/' -e 's/eight/uuid2/' -e 's/eight/uuid2/' -e 's/eight/uuid2/' \
-e 's/eight/uuid2/' -e 's/eight/uuid2/' -e 's/eight/uuid2/' foo |
sed -n '/four/,/eight/p;/eight/q' |
sed 's/uuid1/four/g;s/uuid2/eight/g'
Возвращает:
----fourth asdf
qlvkjqrvlj eight
5+
6
7
8
9
eight eight eight
10
11
12 eight
13 eight
eight qorivjqoerijv
----this is eighth
, что я считаю правильным.
Этот ответ и этот один помог мне.
Объясненная команда:
sed -E -e 'H;1h;$!d;x'
С это
Команды sed H; 1h; $! d; x прочитать весь файл в.
Поскольку вышеупомянутое не использует никакого расширения GNU, оно должно работать на BSD (OSX) sed.Обратите внимание, думал, что этот подход требует sed, который может обрабатывать длинные строки.GNU sed должен быть в порядке.Те, кто использует не-GNU версию sed, должны проверить ее способность обрабатывать длинные строки.
-e 's/four/uuid1/' -e 's/four/uuid1/' -e 's/four/uuid1/' \
-e 's/eight/uuid2/' -e 's/eight/uuid2/' -e 's/eight/uuid2/' -e 's/eight/uuid2/' \
-e 's/eight/uuid2/' -e 's/eight/uuid2/' -e 's/eight/uuid2/' foo
Затем я заменяю первые три four
на uuid1
и первые семь eight
на uuid2
.
Как сказал @JonathanLeffler, если вы увеличите количество замен, становится очень уродливо, но я не нашел обходного пути для версий sed POSIX, я использовал команду из этого ответ .
Если GNU sed недоступен и вы хотите заменить первые 3 вхождения старого на новое, используйте три команды s:
Это хорошо работает, когдаk - небольшое число, но плохо масштабируется до большого k.
sed -n '/four/,/eight/p;/eight/q'
- по умолчанию не печатать;от первой four
до первой eight
выведите строку;когда вы найдете eight
, выходите.
Сначала я попробовал: sed -n '/four/,/eight/p'
, но он мог бы вернуть строки после раздела, который должен быть напечатан.Я использовал этот ответ , чтобы исправить проблему.
Эта команда выбирает линию между первым four
и первым eight
вхождением.
sed 's/uuid1/four/g;s/uuid2/eight/g'
Iзамените uuids на их первоначальные значения.Я делаю это даже для uuid1
, поскольку третий four
может находиться на той же строке, что и четвертый.