Se você estiver usando o GNU sed
, sua melhor opção é usar o comando r
:
sed -i "/ \"'ice field'\"/ r /dev/stdin" mytestfile.txt <<'EOF'
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
EOF
Gostaria de acrescentar várias linhas depois de uma linha correspondente em um arquivo de texto em um script bash. Embora eu não me importe com qual ferramenta escolher para o trabalho, o importante para mim é que eu queira especificar as linhas anexadas "como estão" dentro do script (assim, sem gerar um arquivo adicional que possa mantê-las), acabar em uma variável Bash, e sem ter que citar / escapar nada neles - e para o efeito usando um heredoc 'citado' funcionaria para mim. Aqui está um exemplo, appendtest.sh
:
cat > mytestfile.txt <<'EOF'
"'iceberg'"
"'ice cliff'"
"'ice field'"
"'inlet'"
"'island'"
"'islet'"
"'isthmus'"
EOF
IFS='' read -r -d '' REPLACER <<'EOF'
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
EOF
echo "$REPLACER"
sed -i "/ \"'ice field'\"/a${REPLACER}" mytestfile.txt
Isso infelizmente não funciona:
$ bash appendtest.sh
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
sed: -e expression #1, char 39: unknown command: '"'
... porque sed
falhou quando uma substituição de múltiplas linhas sem escape foi usada. Então minha pergunta é:
sed
para realizar a correspondência em uma linha de texto e inserir / anexar as linhas conforme especificado na variável Bash ( $REPLACER
no exemplo)? OK, encontrado de uma maneira usando perl
:
cat > mytestfile.txt <<'EOF'
"'iceberg'"
"'ice cliff'"
"'ice field'"
"'inlet'"
"'island'"
"'islet'"
"'isthmus'"
EOF
IFS='' read -r -d '' REPLACER <<'EOF'
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
EOF
# echo "$REPLACER"
IFS='' read -r -d '' LOOKFOR <<'EOF'
"'ice field'"
EOF
export REPLACER # so perl can access it via $ENV
# -pi will replace in-place but not print to stdout; -p will only print to stdout:
perl -pi -e "s/($LOOKFOR)/"'$1$ENV{"REPLACER"}'"/" mytestfile.txt
# also, with export LOOKFOR, this works:
# perl -pi -e 's/($ENV{"LOOKFOR"})/$1$ENV{"REPLACER"}/' mytestfile.txt
cat mytestfile.txt # see if the replacement is done
A saída é a desejada:
$ bash appendtest.sh
"'iceberg'"
"'ice cliff'"
"'ice field'"
"'$oasis$'"
"'$ocean$'"
"'$oceanic trench$'"
"'inlet'"
"'island'"
"'islet'"
"'isthmus'"
Tags bash text-processing