Как работать с многострочными строками и интерполяцией строк?

Вот еще один подход awk :

$ awk '{a[$4]=0;a[$5]=1; for(i=6;i<=NF;i++){$i=a[$i]}}1;' file
1 rs6687776 1020428 T C 0 1 0 1 1 1 0 1 1 1 0 1

Объяснение

  • a [$ 4] = 0 ; a [$ 5] = 1; : создает массив a с двумя ключами, $ 4 и $ 5 . Для $ 4 установлено значение 0 , а для $ 5 - 1.
  • для (i = 6; i <= NF; i ++) { $ i = a [$ i]} : для каждого номера поля от 6 до последнего установите для этого поля значение, хранящееся в массиве для найденного нуклеотида.

  • 1; : сокращение от awk для «распечатать эту строку».


Вы также можете сделать это с помощью Perl:

$ perl -lane 's/$F[3]/0/ for @F[5..$#F]; s/$F[4]/1/ for @F[5..$#F]; print "@F"' file
1 rs6687776 1020428 T C 0 1 0 1 1 1 0 1 1 1 0 1

Это та же идея. -a заставляет perl действовать как awk , разбивая каждую строку на пробелы в массив @F . Затем мы заменяем все варианты нуклеотида, найденные в 4-м поле ( $ F [3] , массивы начинаются с 0), на 0 и все варианты 5-го ( $ F [4] ) с 1 . для @F [5 .. $ # F] означает, что замена применяется только к полям с 6 до последнего. Наконец, печатается измененный массив.

2
04.04.2018, 15:28
4 ответа

Данные, введенные пользователем one, two,three

Следующая команда заменит все экземпляры данного ${placeholder}вашим вводом:

sed -i 's/${placeholders}/one/g; s/${different}/two/g; s/${here}/three/g' yourTemplateFile

Если вы используете это в скрипте bash и вводите пользовательский ввод в переменных оболочки, это сделает все замены в одной команде.

0
27.01.2020, 21:52

Вот как это сделать в bash. Вам нужна последняя версия, потому что здесь я полагаюсь на ассоциативные массивы

template=$(cat << 'END_TEMPLATE'
I have some
text with ${placeholders}
in this and some ${different}
ones ${here} and ${there}
END_TEMPLATE
)

mapfile -t placeholders < <(grep -Po '(?<=\$\{).+?(?=\})' <<< "$template" | sort -u)

declare -A data
for key in "${placeholders[@]}"; do
    read -p "Enter the '$key' value: " -r data[$key]
done

t=$template
while [[ $t =~ '${'([[:alnum:]_]+)'}' ]]; do
    t=${t//"${BASH_REMATCH[0]}"/"${data[${BASH_REMATCH[1]}]}"}
    #      ^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    #      |                    + the value the user entered
    #      + the placeholder in the text
done

echo "$t"
2
27.01.2020, 21:52

Предполагая [a] , что ни \<новая строка>, ни символы \, $или `не используются в многострочной строке (или они правильно заключены в кавычки ), здесь -документ (и переменные )— ваш лучший вариант:

#!/bin/sh

placeholders="value one"
different="value two"
here="value three"
there="value four"

cat <<-_EOT_
I have some
text with ${placeholders}
in this and some ${different}
ones ${here} and ${there}.
_EOT_

При выполнении:

$ sh./script
I have some
text with value one
in this and some value two
ones value three and value four.

Конечно, правильно играя с кавычками, можно было бы обойтись даже одной переменной:

$ multilinevar='I have some
> text with '"${placeholders}"'
> in this and some '"${different}"'
> ones '"${here}"' and '"${there}"'.'
$ echo "$multilinevar"
I have some
text with value one
in this and some value two
ones value three and value four.

Оба решения могут принимать многострочные переменные-заполнители.


[а] Из инструкции:

... the character sequence \<newline> is ignored, and \ must be used to quote the characters \, $, and `....

10
27.01.2020, 21:52

Протестировано с помощью приведенного ниже сценария, все работает нормально

echo "enter count of userinput required"
read c
for ((i=1;i<=$c;i++))
do
echo "enter the values"
read input_$i
done

awk -v i="$input_1" -v j="$input_2" -v k="$input_3" -v l="$input_4"   '{gsub(/\${placeholders}/,i,$0);gsub(/\${different}/,j,$0);gsub(/\${here}/,k,$0);gsub(/\${there}/,l,$0);print $0}' filename >>filename_tmp && mv filename_tmp filename
0
27.01.2020, 21:52

Теги

Похожие вопросы