В настоящее время я использую AWK для поиска и замены части строки после первых трех вхождений шаблона. Строка отформатирована следующим образом: func(tempID="39849235",count='12');
, и в файле есть много таких строк, как показано ниже:
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
С использованиемэта ссылка, мне удалось найти метод использования AWK для поиска и замены первых трех экземпляров строки. Я изменил его на то, что мне было нужно, и фрагмент моего скрипта приведен ниже:
id=12349876
awk -v id="$id" 'BEGIN {matches=0}
matches < 3 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id"\""); matches++ }
{ print $0 }' filName.py >filName.py.changed
Целью приведенного выше кода является сопоставление любой строки, содержащей tempID, и замена числа, назначенного tempID, на значение, хранящееся в переменной с именем $id
. Поиск и замена работают хорошо, но теперь я хочу заменить экземпляры 4-9 другим числом. Я попробовал следующий метод, но он все еще заменил только первые 5 экземпляров tempID:
id2=39843237
awk -v id2="$id2" 'BEGIN {matches=4}
matches < 9 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id2"\""); matches++ }
{ print $0 }' filName.py >filName.py.changed
Есть ли другой способ реализовать это так, чтобы этот диапазон значений был заменен? Это не обязательно с AWK, это может быть с sed или любой другой утилитой Linux. Кроме того, решение не обязательно должно заканчиваться в определенной точке и разрешено заменять все экземпляры после третьей строки, но если есть решение, которое может это сделать, это было бы плюсом.
решение1
Ваши matches=4
и matches < 9
означают "предположим, что уже было 4 совпадения, действовать, пока их не будет 9". Вот почему заменяются первые 5 экземпляров. Вам нужно начать с 0, как и раньше, затем включить нижний предел в логику:
id2=39843237
awk -v id2="$id2" 'BEGIN {matches=0}
matches >=3 && matches < 9 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id2"\"") }
/.*tempID.*/ { matches++ }
{ print $0 }' filName.py >filName.py.changed
Обратите внимание, что вам нужно сделать замену в соответствии со значением, matches
но вам нужно увеличивать это значение каждый раз, когда происходит совпадение. Ваш исходный код заменил текст и увеличил значение в одном блоке. Когда не было замены из-за того, что matches
оно было слишком большим, значение больше не увеличивалось, но это больше не имело значения. Теперь вы не можете обойтись этим простым подходом. Когда нет замены из-за того, matches
чтослишком низко, вам все равно придется увеличить значение, если будет найдена соответствующая строка.
Отсюда и два {}
блока с отдельными условиями.