Então, é isso que eu usei para obter o material de origem:
cat <<F1 >/tmp/f1 ; cat <<F2 >/tmp/f2
$(for i in 1 2 3 4 5 ; do { \
printf "00%s" $i ; printf ";%s" \
abc def ghi jkl pqr ; echo ; } ; done)
F1
$(for i in 1 2 3 4 5 ; do {\
printf "00%s" $i ; echo ";mno" ; } ; done)
F2
Fornece:
001;abc;def;ghi;jkl;pqr
002;abc;def;ghi;jkl;pqr
003;abc;def;ghi;jkl;pqr
004;abc;def;ghi;jkl;pqr
005;abc;def;ghi;jkl;pqr
001;mno
002;mno
003;mno
004;mno
005;mno
Eu testei isso de várias maneiras, e este é o comando resultante:
% sed -e 'R /tmp/f2' /tmp/f1 |\
sed -r 'N;s/(.*)(;[^;]*)\n[^;]*(.*)//'
Isso é GNU sed only - porque o GNU oferece a função R que podemos ler em um arquivo separado linha por linha em sincronia com nossa entrada. Isso significa sem ramificação e sem loop. Dessa forma, espero que sed trabalhe com mais eficiência do que awk , porque não precisaria ler o conteúdo completamente na memória antes de operar e pode operar em uma transmissão ao vivo.
Eu tentei fazer isso funcionar sem a invocação |pipe e segundo sed , mas porque sed anexou / tmp / f2 ao seu próprio stdout nada que eu tentei permitiu edite no fluxo sem o |pipe . sed primeiro agrupa os dois arquivos no fluxo e edita o resultado no outro lado do |pipe .
De qualquer forma, um |pipe ainda é transmitido, mas você precisa de dois sed s. Execute o comando sed acima em seus dados e:
OUTPUT
> 001;abc;def;ghi;jkl;mno;pqr
> 002;abc;def;ghi;jkl;mno;pqr
> 003;abc;def;ghi;jkl;mno;pqr
> 004;abc;def;ghi;jkl;mno;pqr
> 005;abc;def;ghi;jkl;mno;pqr
Veja como funciona:
sed -r 'N;s/(.*)(;[^;]*)\n[^;]*(.*)//'
-
N porque já sabemos que
sed está anexando cada linha sucessiva de f2 àquelas em f1 , a primeira coisa que fazemos depois de receber uma linha é Puxe o N ext.
-
s tendo juntado as duas linhas que precisamos no espaço padrão, iniciamos a função s earch and replace
001; abc; def; ghi; jkl ; pqr \ n001; mno
-
\ 1 (. *) primeiro informe sed to ( group * tudo que for encontrado ) da parte mais à esquerda do espaço de padrões na referência de referência até ...
001; abc; def; ghi; jkl * ; pqr * \ n001; mno
-
\ 2 (; [^;] *) \ n encontra uma string que consiste em um ...
- ; ponto e vírgula então ...
-
[^;] * uma string consistindo inteiramente de ^ no; ponto e vírgula imediatamente seguido por
-
\ n o caractere
\n ewline adicionado quando extraímos a linha f2 com N e o qual será descartado
-
() Dessa forma, fazemos referência ao
( do último campo delimitado por ponto-e-vírgula ) da linha em f1 to
-
[^;] * começando com a linha f2 , pesquisamos e descartamos todos os caracteres até encontrarmos um ponto-e-vírgula e
001; abc; def; ghi; jkl; pqr \ n001 * ; mno *
-
\ 3 (. *) armazenamos tudo o que resta na backreference
-
\ 1 \ 3 \ 2 uma vez que dividimos a string, pois exigimos que tudo o que resta é colocá-la de volta na ordem correta , então inserimos antes de e terminamos com esse ciclo de substituição de pesquisa até recebermos uma nova linha