bash - ultima - Como substituir uma linha inteira em um arquivo de texto pelo número de linha




sed substituir caracteres especiais/ (6)

Dado este arquivo de teste (test.txt)

Lorem ipsum dolor sit amet,
consectetur adipiscing elit. 
Duis eu diam non tortor laoreet 
bibendum vitae et tellus.

o seguinte comando substituirá a primeira linha por "newline text"

$ sed '1 c\
> newline text' test.txt

Resultado:

newline text
consectetur adipiscing elit. 
Duis eu diam non tortor laoreet 
bibendum vitae et tellus.

Mais informações podem ser encontradas aqui

http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-append-insert-replace-and-count-file-lines/

Eu tenho uma situação onde eu quero um script bash para substituir uma linha inteira em um arquivo. O número da linha é sempre o mesmo, de modo que pode ser uma variável codificada.

Eu não estou tentando substituir algumas sub-string nessa linha, eu só quero substituir essa linha inteiramente com uma nova linha.

Existe algum método bash para fazer isso (ou algo simples que pode ser jogado em um script .sh).


Excelente resposta de Chepner. Está trabalhando para mim no bash Shell.

 # To update/replace the new line string value with the exiting line of the file
 MyFile=/tmp/ps_checkdb.flag

 `sed -i "${index}s/.*/${newLine}/" $MyFile`

Aqui
index - linha não
newLine - nova string de linha que queremos substituir.


Da mesma forma abaixo do código é usado para ler uma linha específica no arquivo. Isso não afetará o arquivo real.

LineString=`sed "$index!d" $MyFile` 

Aqui
!d - irá deletar as linhas que não a linha no $index Então nós iremos obter a saída como string de linha de $index no arquivo.


Na verdade, usei esse script para substituir uma linha de código no arquivo cron nos servidores UNIX da empresa por algum tempo atrás. Nós o executamos como shell script normal e não tivemos problemas:

#Create temporary file with new line in place
cat /dir/file | sed -e "s/the_original_line/the_new_line/" > /dir/temp_file
#Copy the new file over the original file
mv /dir/temp_file /dir/file

Isso não vai pelo número da linha, mas você pode facilmente mudar para um sistema baseado em número de linha colocando o número da linha antes do s/ e colocando um curinga no lugar da the_original_line .


No mac eu usei

sed -i '' -e 's/text-on-line-to-be-changed.*/text-to-replace-the=whole-line/' file-name

Você pode até passar parâmetros para o comando sed:

test.sh

#!/bin/bash
echo "-> start"
for i in $(seq 5); do
  # passing parameters to sed
  j=$(($i+3))
  sed -i "${j}s/.*/replaced by '$i'!/" output.dat
done
echo "-> finished"
exit 

saída orignial.dat:

a
b
c
d
e
f
g
h
i
j

Executar ./test.sh fornece o novo output.dat

a
b
c
replaced by '1'!
replaced by '2'!
replaced by '3'!
replaced by '4'!
replaced by '5'!
i
j

no bash, substitua N, M pelos números de linha e xxx yyy pelo que você quer

i=1
while read line;do
  if((i==N));then
    echo 'xxx'
  elif((i==M));then
    echo 'yyy'
  else
    echo "$line"
  fi
  ((i++))
done  < orig-file > new-file

EDITAR

De fato, nesta solução existem alguns problemas, com caracteres "\ 0" "\ t" e "\"

"\ t", pode ser resolvido colocando IFS = before read: "\", no final da linha com -r

IFS= read -r line

mas para "\ 0", a variável é truncada, não existe uma solução em puro bash: Atribua string contendo caractere nulo (\ 0) a uma variável em Bash Mas em arquivo de texto normal não há nenhum caractere nul \ 0

Perl seria uma escolha melhor

perl -ne 'if($.==N){print"xxx\n"}elsif($.==M){print"yyy\n"}else{print}' < orig-file > new-file




sed