Substituir a primeira linha no arquivo de texto pela linha i de outro arquivo de texto

3

Posso fazer o seguinte no terminal? (escrito em pseudocódigo)

for (int i=1;i<=5;i++) {
replace first line of fileout.text by i-th line of filein.txt 
}

eu acho que de alguma forma envolve o uso de sed, mas eu não sei como sed de um arquivo para outro.

EDITAR : enquadro a resposta de Htorque dentro de um loop:

for (( i = 1 ; i <= 10 ; i++ )); do
    line=$(sed -n "${i}p" filein.txt)
    sed -i "1c\$line" fileout.txt
done

que funciona como um encanto. É possível substituir a cadeia fixa '10' no contador pelo número real de linhas de filein.txt:

nline=$(sed -n '$=' filein.txt)
for (( i = 1 ; i <= $nline ; i++ )); do
    line=$(sed -n "${i}p" filein.txt)
    sed -i "1c\$line" fileout.txt
done
    
por user2413 03.11.2010 / 09:01

2 respostas

3

Para substituir a primeira linha do FILE.out pela i-ésima linha do FILE.in eu faria:

 i=<line-number>
 line=$(sed -n "${i}p" FILE.in)
 sed -i "1c\$line" FILE.out

Se i não existir em FILE.in, a primeira linha de FILE.out será excluída (vazia).

Se $line contiver algum caractere especial (por exemplo, barra invertida, dólar), você precisará escapar deles.

Não tem 100% de certeza de que isso não pode acontecer em outro lugar.

    
por htorque 03.11.2010 / 11:32
1

Existem duas partes para o programa: obter a saída desejada e, em seguida, substituir o conteúdo do arquivo original por essa saída:

#!/bin/sh
# output the first five lines of the first argument
# followed by all but the first of the second argument
# if successful, replace the second argument with the
# result

# cribbed almost entirely from Kernighan & Pike's
$ "The Unix Programming Environment" script "overwrite"

case $# in
0|1)        echo 'Usage: replace5 filea fileb' 1>&2; exit 2
esac

filea=; fileb=
new=/tmp/$$.new; old=/tmp/$$.old
trap 'rm -f $new; exit 1' 1 2 15    # clean up files

# collect input
if head -5 $filea >$new && tail -n +2 $fileb >> $new
then
    cp $filea $old   # save original file
    trap 'trap "" 1 2 15; cp $filea $old   # ignore signals
          rm -f $new $old; exit 1' 1 2 15   # during restore
    cp $new $filea
else
    echo "replace5: failed, $filea unchanged" 1>&2
    exit 1
fi
rm -f $new $old
    
por msw 03.11.2010 / 11:45