Как заменить значение заголовка в файле строкой и случайно сгенерированным числом? - PullRequest
1 голос
/ 16 мая 2019

У меня есть файлы в каталоге, которые выглядят так:

aaa   bbbbb   cccc  value1=xxxxxvalue2=yyyy
body body body
body body body 
body body body 
aaa   bbbbb   cccc  value1=xxxx

Как мне заменить все, что находится между "value1 =" и "value2 =" в заголовке строкой (sevens.eighteen. Ниже)и случайно сгенерированное число длиной 20 (ниже 11234567890123456789)?

например: aaa bbbbb cccc value1 = sevens.eighteen.11234567890123456789 = yyyy

Я пробовал варианты ниже, но я не получаю то, что хочу.

sed -i '1 s/^.*value=/yoursubstitution value=/; $ s/^.*value=/yoursubstitution value=/'

Вот результаты, которые я хочу видеть во всех файлах в этом каталоге:

aaa   bbbbb   cccc  value1=sevens.eighteen.11234567890123456789value2=yyyy
body body body
body body body 
body body body 
aaa   bbbbb   cccc  value1=xxxx

Ответы [ 3 ]

1 голос
/ 16 мая 2019

Существует несколько способов создания случайной цифры:

RAND_NR="$(tr -cd "[:digit:]" < /dev/urandom | head -c 20)"

Затем вы можете заменить значение с помощью sed:

sed "s/value1=.*value2=/value1=sevens.eighteen.${RAND_NR}value2=/" file

Двойные кавычки в sed для расширения переменной RAND_NR.

Вывод:

aaa   bbbbb   cccc  value1=sevens.eighteen.76744539817863807290value2=yyyy
body body body
body body body 
body body body 
aaa   bbbbb   cccc  value1=xxxx
1 голос
/ 16 мая 2019

С GNU awk для 3-го аргумента для сопоставления () и -i inplace для редактирования "на месте" вам просто нужна одна команда:

$ cat tst.awk
BEGIN { srand(seed) }
(FNR==1) && match($0,/(.*value1=).*(value2=.*)/,a) {
    $0 = a[1] "sevens.eighteen." int(10000000000000000000 + rand()*90000000000000000000) a[2]
}
{ print }

$ awk -i inplace -v seed="$RANDOM" -f tst.awk *

Например:

$ awk -v seed="$RANDOM" -f tst.awk file
aaa   bbbbb   cccc  value1=sevens.eighteen.77242153065798582272value2=yyyy
body body body
body body body
body body body
aaa   bbbbb   cccc  value1=xxxx

$ awk -v seed="$RANDOM" -f tst.awk file
aaa   bbbbb   cccc  value1=sevens.eighteen.59551444957943291904value2=yyyy
body body body
body body body
body body body
aaa   bbbbb   cccc  value1=xxxx

Обратите внимание, что приведенное выше будет работать только в первой строке каждого входного файла, поэтому даже если регулярное выражение совпадает с другой строкой, оно не будет изменено.

Я вижу, вы задали другой идентичный вопрос, отличный от того, который вы хотитесделать это для первой и последней строк.Просто переместите код, который меняет $ 0, в функцию, так как вам нужно будет вызвать ее дважды сейчас и сохранить / изменить предыдущую строку, а не текущую, чтобы у вас была последняя строка для работы в ENDFILE (также расширение GNU awk):

$ cat file
aaa   bbbbb   cccc  value1=xxxxxvalue2=yyyy
body body body
body body body
body body body
aaa   bbbbb   cccc  value1=xxxx,value2=yyyy

$ cat tst.awk
BEGIN { srand(seed) }
NR==1  { fmt() }
NR > 1 { print prev }
{ prev = $0 }
ENDFILE { fmt(); print }

function fmt() {
    if ( match($0,/(.*value1=).*(value2=.*)/,a) ) {
        $0 = a[1] "sevens.eighteen." int(10000000000000000000 + rand()*90000000000000000000) a[2]
    }
}

$ awk -v seed="$RANDOM" -f tst.awk file
aaa   bbbbb   cccc  value1=sevens.eighteen.55152151176931606528value2=yyyy
body body body
body body body
body body body
aaa   bbbbb   cccc  value1=sevens.eighteen.98796005800472494080value2=yyyy
1 голос
/ 16 мая 2019

С одним файлом.

# create a 20 digit random number with bash
for ((i=0;i<20;i++)); do num="${num}${RANDOM: -1:1}"; done

# replace string with GNU sed
sed -E '1 s/(value1=).*(value2=.*)/\1sevens.eighteen.'"$num"'\2/' file

Вывод:

aaa   bbbbb   cccc  value1=sevens.eighteen.39489360437938728734value2=yyyy
body body body
body body body 
body body body 
aaa   bbbbb   cccc  value1=xxxx
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...