Você pode usar os comandos vim
diretamente com um documento aqui (que é especialmente útil para substituições irregulares):
#!/bin/ksh
vim weatherfile <<EOF
:3,8s/snow/dry/g
:wq
EOF
Um script que cria um arquivo para a precipitação climática é
#!/bin/ksh
x=10
b=snow
c=rain
d=snow
e=hail
echo "$x,$b,$c,$d,$e" > weatherfile
exit 0
dado
3,8s/snow/dry/g
Para a pesquisa e substituição, qual é a melhor maneira de implementar isso em um script?
Da perspectiva do comando, sed
seria necessário?
Meus pensamentos são de que o seguinte deve funcionar:
sed 3,8s/snow/dry/g weatherfile
Mas e se sed
não puder ser usado? Eu precisaria abrir e fechar o arquivo e alguma forma de como executar
:3,8s/snow/dry/g
enquanto o arquivo está aberto? Como isso pode ser implementado?
Você pode fazer isso inteiramente no shell com um script como este:
#!/bin/bash
line_num=0
while IFS= read -r line
do
: $((line_num++))
if [[ line_num -ge 3 && line_num -le 8 ]]
then
printf "%s\n" "${line/snow/dry}"
else
printf "%s\n" "$line"
fi
done
(eu testei isso em bash,
e relatórios Andrey
que funciona em ksh
mas não funcionará em todas as versões compatíveis com POSIX de sh
.)
Ele lê linhas da entrada padrão.
Conta linhas (com line_num=0
e : $((line_num++))
porque você deseja especificar um intervalo de números de linha;
se esse requisito for removido,
as instruções referenciando line_num
podem ser excluídas.
O teste condicional
if [[ line_num -ge 3 && line_num -le 8 ]]
significa “IF (line_num ≥ 3) AND (line_num ≤ 8)”,
correspondendo ao intervalo 3,8
, isto é, 3 a 8.
(Que é um ponto de confusão para iniciantes Unix,
quem espera que 3,8
signifique "3 e também 8",
e espera que "3 a 8" seja representado como 3-8
-
isto é, a convenção usada pelas caixas de diálogo de impressão no Windows
para imprimir um subconjunto das páginas de um documento.)
Nas linhas que estão no intervalo, ele usa o
${parameter/pattern/string)
forma de expansão de parâmetro para substituir "neve" por "seco" antes de gravar a linha na saída padrão. Linhas fora do intervalo são escritas sem modificações.
Isso mudará a primeira ocorrência (se houver) de "neve" em cada linha
dentro do alcance. Para substituir todas as ocorrências,
use ${line//snow/dry}
(insira um /
extra antes da "neve").
Não estou claro sobre o quadro geral do que você quer.
Se você modificou seu script (vamos chamá-lo de weather.sh
)
escrever para stdout em vez do arquivo, então você poderia dizer
./weather.sh | ./do_substitute.sh > weatherfile
Se você quiser criar weatherfile
da mesma maneira que está fazendo agora,
mas depois mudá-lo depois, você poderia fazer
./do_substitute.sh < weatherfile > weatherfile.tmp
mv weatherfile.tmp weatherfile
Tags text-processing sed