Como adicionar novas linhas de outro arquivo com sed

Como adicionar novas linhas de outro arquivo com sed

Estou tentando encontrar o sedcomando para poder colocar filenameno filename1. Estes são meus dois arquivos separados.

ENTRADA filenametem:

Cindy   11 22 54
Chester 48 12 84

ENTRADA filename1tem:

 Name  Class1 Class2 Class3
Lee      92     94     88
Chancy   91     85     95
Dora     99     77     96


Jefferry 84     98     90

Este é o resultado que preciso (saída):

Name   Class1 Class2 Class3
Lee      92     94     88
Chancy   91     85     95
Dora     99     77     96
Cindy    11     22     54
Chester  48     12     84
Jefferry 84     98     90

Se eu precisar esclarecer alguma coisa me avise. Basicamente, Cindy e Chester têm que estar entre Dora e Jefferry.

Responder1

Para adicionar todas as linhas de filenameaté filename1usando sedo comando, você pode fazer o seguinte:

sed r filename1 filename

Observe, no entanto, que o resultado será um pouco diferente da saída da sua pergunta, a saber:

Name  Class1 Class2 Class3
Lee      92     94     88
Chancy   91     85     95
Dora     99     77     96
Jefferry 84     98     90
Cindy    11     22     54
Chester  48     12     84

Editar

Algumas sedinformações adicionais úteis para esta questão:

  • Para adicionar filenameapós a 4ª linha de filename1:

    sed '4 r filename' filename1

  • Para adicionar filenameuma linha posterior que começa com "Dora" em filename1:

    sed '/^Dora/ r filename' filename1

  • Para adicionar filenameapós a 4ª linha e remover quaisquer linhas em branco de filename1:

    sed '/^$/d;4 r filename' filename1

Responder2

Não deveria haver nenhuma ordem, se bem me lembro.

Nesse caso:

$ cat file2 file1 | column -t
Name      Class1  Class2  Class3
Lee       92      94      88
Chancy    91      85      95
Dora      99      77      96
Jefferry  84      98      90
Cindy     11      22      54
Chester   48      12      84

Responder3

Se você fizer:

sed r file1 file2

... então sedtentará e não conseguirá anexar um rarquivo ead com um nome de arquivo de comprimento nulo a cada linha de entrada de ambos os arquivos de entrada nomeadosfile1efile2. Esse comando não é essencialmente diferente de:

sed '' file1 file2

... exceto que ré mais lento.

É isso que eu quero dizer:

seq 1  5 > file1
seq 6 10 > file2
strace sed r file[12]

...
write("1\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
write("2\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
write("3\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
write("4\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
write("5\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
read(3, "", 4096) = 0
close(3) = 0
open("file2", RDONLY) = 3
write("6\n", 21) = 2
open("", O_RDONLY) = -1 ENOENT (No such file or directory)
write("7\n", 21) = 2
...

Veja a open("" ...)falha comENOENTseguindo cada linha escrita? Esse é o rcomando vazio ead sedexecutado. Você não percebe as falhas porque sedé especificado que não deve reclamar de um arquivo ead inexistente rnomeado em seu script, mas sim continuar como se nada tivesse acontecido ao tentar rler um.

E talvez issovisualcomo se funcionasse porque você deseja apenas anexar um arquivo ao final de outro - para conectar catdois arquivos - o que sedacontece por padrão quando dois arquivos de entrada são nomeados - ele lê o primeiro e depois o próximo. Mas se o rcomando ead realmente funcionasse, o rarquivo ead nomeado seria anexado inteiramente aotodolinha de entrada.

Assim:

seq 3 > file
printf %s\\n a b c | 
sed r\ file

a
1
2
3
b
1
2
3
c
1
2
3

Para anexar o conteúdo de um arquivo a outro, você pode fazer:

cat < file2 >> file1

Para anexar após apenas um determinado ponto da entrada, você tem algumas opções. sedestá entre eles:

sed -e '/match/{r file2' -e:n -e 'n;bn' -e \} file1

... que deve funcionar com praticamente qualquer arquivo sed.

Ou então, se você tiver um POSIX sed:

{ sed /match/q; cat file2 -; } < file1

...que deveria ser muito mais eficiente.

Ambos os métodos garantem que o conteúdo dofile2é rlido apenas uma vez e somente imediatamente após a primeira ocorrência matchdefile1.

Outra maneira poderia ser assim:

cat file2 | sed /match/r\ /dev/fd/0 file1

... que leria um arquivo de comprimento nulo após cada correspondência após a primeira ...

informação relacionada