Как заменить третье вхождение строки в файле с помощью sed
команды.
Пример:
Изменение только третье вхождение is
в us
в файле.
Мой входной файл содержит:
hai this is linux.
hai this is unix.
hai this is mac.
hai this is unchanged.
Я ожидаю, что результат будет:
hai this is linux.
hai thus is unix.
hai this is mac.
hai this is unchanged.
text-processing
sed
perl
Sureshkumar
источник
источник
sed
это не правильный инструмент для работы.Ответы:
Это намного проще сделать
perl
.Чтобы изменить 3- е вхождение:
Чтобы изменить каждый 3- й случай:
источник
Когда замена строки происходит только один раз в строке, вы можете комбинировать различные утилиты.
Когда вход находится в файле «input» и вы заменяете «is» на «us», вы можете использовать
источник
is
на строку.Сценарий ниже (с использованием синтаксиса GNU
sed
) можно использовать для редактирования на месте, а не для вывода, поскольку он останавливает печать строк после желаемой замены:Если вам нравится решение Чороба, вы можете изменить выше, чтобы
который выводит все строки
Или вы должны поместить все строки в пространство образца (в памяти, поэтому будьте осторожны с ограничением размера) и выполните замену
источник
Вы можете использовать
sed
для этого, если ранее новые строки были заменены на любые другие символы, например:И то же самое с чистым (GNU)
sed
:(
sed
замена новой строки бессовестно похищенной с https://stackoverflow.com/a/1252191/4488514 )источник
sed
специфический для GNU синтаксис, вы также можете использовать егоsed -z 's/is/us/3'
.-z
должно быть, какая-то новая функция, мояGNU sed version 4.2.1
ничего не знает об этой опции.\x0
шаг.Этот бит
sed
просто переносит количествоis
появлений с одной строки на другую. Он должен надежно обрабатывать столькоis
es на строку, сколько вы набрасываете на него, и ему не нужно буферизовать старые строки, пока он это делает - он просто сохраняет один символ новой строки для каждогоis
, с чем встречается, который не является частью другого слова.В результате он будет изменять только третье вхождение в файле - и он будет иметь число в строке. Так что если файл выглядит так:
... это будет печатать ...
Сначала он обрабатывает края, вставляя пробел в начало и конец каждой строки. Это немного облегчает определение границ слов.
Затем он ищет действительные значения
is
, вставляя\n
ewline до того, как все вхожденияis
этого предшествуют нулю или одному знаку препинания, за которым следует пробел. Он делает еще один проход и удаляет все электронные\n
строки, которым непосредственно предшествует непробельный символ. Эти оставленные маркеры будут совпадатьis.
иis
, но неthis
или?is
.Затем он собирает каждый маркер в конец строки - для каждого
\ni
совпадения в строке он добавляет линию\n
ewline к концу строки и заменяет ее либо на,i
либо наu
. Если в\n
конце строки собраны 3 строки, тогда используется символ u, иначе - i. Первый раз, когда используется au, также является последним - замена запускает бесконечный цикл, который сводится кget line, print line, get line, print line,
и так далее.В конце каждого цикла цикла try он очищает вставленные пробелы, печатает только до первой встречающейся новой строки в пространстве шаблона и возвращается снова.
Я добавлю
l
команду ook в начало цикла, например:... и посмотрим, что он делает, как работает с этим входом:
... так вот что он делает:
Это имеет больше смысла, может быть, с большим количеством
is
es в строке:Это практически то же самое, но написано с помощью POSIX BRE и элементарной обработки аргументов.
... получает ...
... и если я включу
${dbg}
:... мы можем смотреть это повторяться ...
источник
Вот логическое решение, которое использует
sed
иtr
должно быть записано в сценарии, чтобы оно работало. Приведенный ниже код заменяет каждое третье вхождение слова, указанного вsed
команде. Заменитьi=3
наi=n
, чтобы сделать эту работу для любогоn
.Код:
Почему это работает:
Предположим, текстовый файл
a b b b b a c a d a b b b a b e b z b s b a b
.Когда n = 2: мы хотим заменить каждое второе вхождение
b
.a b b b b a c a d a b b b a b e b z b s b a b
. . ^ . ^ . . . . . . ^ . . ^ . . . ^ . ^ . ^
Когда n = 3: мы хотим заменить каждое третье вхождение
b
.a b b b b a c a d a b b b a b e b z b s b a b
. . . ^ . . . . . . . ^ . . . . ^ . . . . . ^
Когда n = 4: мы хотим заменить каждое третье вхождение
b
.источник