вставить переменный текст после другого переменного текста в определенной строке

вставить переменный текст после другого переменного текста в определенной строке

Я пытаюсь вставить переменный текст после другого переменного текста на определенной строке. Ниже представлена ​​моя попытка на данный момент, насколько я могу судить, если я смогу экранировать кавычки так, awkчтобы переменная была видна и все еще применялась, то это должно сработать, но я понятия не имею, как это сделать:

#!/bin/sh

VAR=$(head -n1 ~/Scripts/tmp/file.txt)
VAR1=$(head -n1 ~/Scripts/tmp/file1.txt)

awk '/$VAR/ { print; print "$VAR1"; next }1' ~/Scripts/tmp/file.txt

решение1

Чтобы передать строки в скрипт awk, передайте их через переменные окружения.

export VAR VAR1
awk '
    1
    $0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt

Я реорганизовал ваш скрипт, чтобы упростить логику. Я также заменил сопоставление регулярных выражений сравнением строк: при сопоставлении регулярных выражений $VARбудет рассматриваться как регулярное выражение, оно не будет выполнять сравнение строк. И /$VAR/даже не будет использовать значение VAR(это синтаксис Perl, а не awk), которое вам match($0, VAR)для этого понадобится.

Примечание о некоторых других решениях, которые на самом деле не работают (они работают только в том случае, если переменные не содержат никаких специальных символов; какой именно символ является специальным, зависит от метода):

  • awk -v awkvar="$VAR" '$0 == awkvar …'расширяет обратные косые черты в содержимом строки.
  • awk "/$VAR/" …заставляет оболочку развернуть значение VARкак фрагмент awk. Например, если file.txtсодержит ^/ {system("touch ~/naughty")} /, то команда touch ~/naughtyвыполняется.

Альтернативный подход — заставить awk прочитать все файлы.

awk '
    BEGIN { VAR1 = getline <"~/Scripts/tmp/file1.txt"; }
    NR == 1 {VAR = $0}
    1
    $0 == ENVIRON["VAR"] {print ENVIRON["VAR1"]}
' ~/Scripts/tmp/file.txt

решение2

Одно из возможных решений AWK:

   awk '/'$VAR'/ { print; print "'$VAR1'"; next }1'

разбейте кавычки вокруг всех ваших внешних переменных.

Другое возможное решение, как и в другом посте, с передачей переменных, — это передача VAR1 как переменной awk, но я думаю, что вам все равно нужно сделать экранирование блока одинарных кавычек для шаблона с использованием VAR:

 awk -v var=$VAR1 '/'$VAR'/ { print; print var; next }1'

Вместо этого вы можете попробовать sed :) он специально разработан для такого рода замены.

 sed "s/$VAR.*/\0\n$VAR1/" ~/Scripts/tmp/file.txt     

Если вы можете иметь несколько экземпляров VAR в одной строке, то добавьте g в конец команды sed (глобальная), чтобы она не останавливалась на первом найденном совпадении:

 sed "s/$VAR.*/\0 $VAR1/g" ~/Scripts/tmp/file.txt 

ВАЖНО!: убедитесь, что символ «/» не встречается в переменной VAR или VAR1. Если это так, вам нужно экранировать его для awk или sed. В качестве альтернативы с помощью sed вы можете изменить разделитель для команды на что-то другое, например, «;», например:

 sed "s;$VAR.*;\0\n$VAR1;" ~/Scripts/tmp/file.txt

Объяснение команды sed:
Мы используем двойные кавычки вместо одинарных вокруг команды sed, чтобы переменные, такие как VAR и VAR1, были заменены их значениями. Это происходит до того, как команда будет выполнена sed, поэтому, если / может присутствовать в содержимом переменной, вам нужно обратиться к ней (это справедливо и для awk).
's' указывает на то, что вы пишете команду подстановки в форме:
s/<шаблон>/<шаблон замены>/
'/' сразу после s является разделителем, который будет использоваться для разделения разделов команды. поэтому, если вы поместите ;, вы должны использовать ; везде, как показано выше. Шаблоном для сопоставления будет содержимое переменной $VAR. Шаблон подстановки - \0, что означает вывод того, что совпало с шаблоном, новой строки '\n' и содержимого VAR2.

УПС, не увидел части о строке ниже... фиксированные шаблоны.

решение3

Если вы хотите использовать awk, вам необходимо передать bashпеременную awkс -vопцией :

awk -v v=$VAR -v v1=$VAR1 '/v/ { print; print v1; next }1' ~/Scripts/tmp/file.txt

Но проверьте ответ Роба для более правильного и подробного решения.

Связанный контент