Как выполнить замену строки указанное количество раз с помощью команд Linux?

#awk #sed

#awk #sed

Вопрос:

Я использую следующую команду sed для замены строки

 sed -i "s|find string|replace string|g" inputfile
  

Но это заменит все вхождения. (Я думаю, g это для Global замены)

Как я могу выполнить замену строки только указанное количество раз, т. е. 10 или 15 раз, используя sed, grep или awk ..?

Комментарии:

1. superuser.com/questions/394282/…

Ответ №1:

Вы могли бы сделать:

  perl -pe '$i   while($i < 10 amp;amp; s/pattern/replace/)' input
  

В awk:

  awk '{ while( i< c amp;amp; sub( "pattern", "replace" )) i =1}1' c=10 input
  

Комментарии:

1. -p заставляет perl перебирать свои входные данные и печатать каждую строку, и -e просто указывает код для запуска (следующий аргумент после -e ).

2. i =1 это то же самое, что i

3. @jotne i — это выражение, но i =1 это оператор. В качестве побочного эффекта, i увеличивается i , так что в этом смысле они семантически похожи, но они оцениваются по-разному при использовании в RHS присваивания. Я нахожу это гораздо более удобным в использовании i =1 , поскольку это проясняет намерение.

Ответ №2:

pur sed но лучше не использовать sed для решения такой проблемы, предпочитайте awk (или perl)

 sed -n -e '1h;1!H
$ {s/.*//;x
   t loop
:loop
   s|find string|replace string|
   t occur
   b print
:occur
   x
   s/$/o/
   t count
:count
   s/o{10}/amp;/
   x
   t print
   b loop
:print
   p
   }' YourFile
  

10 в s/o{10}/amp;/ — это желаемое количество встреч. использование s//;t label как если бы /goto. без ‘else’, много s//;t .

Сначала весь файл необходимо загрузить в рабочий буфер (по умолчанию sed работает на строку). Кроме того, в качестве счетчика используется вторичный буфер.

Комментарии:

1. Хорошая техника. Но нет необходимости считывать весь файл во временный буфер: sed ':loop; x; s/o{10}/amp;/; x; t; s/pattern/replace/; t count; b; :count; x; s/^/o/; x; t loop;'

Ответ №3:

Вот другая awk версия.

 awk 'c amp;amp; sub("pattern","replace") {c--}1' c=2 file
  

Ответ №4:

Вот более читаемая awk версия:

 awk '{for(i=0; i<15; i  ) sub("pattern", "replacement"); print $0}' file