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