Eu tenho dois arquivos paralelos com o mesmo número de linhas em dois idiomas e planejo mesclar esses dois arquivos linha por linha com o delimitador |||
. Por exemplo, os dois arquivos são os seguintes:
Arquivo A:
1Mo 1,1 I love you.
1Mo 1,2 I like you.
Hi 1,3 I am hungry.
Hi 1,4 I am foolish.
Arquivo B:
1Mo 1,1 Ich liebe dich.
1Mo 1,2 Ich mag dich.
Hi 1,3 Ich habe Durst.
Hi 1,4 Ich bin neu.
A saída esperada é assim:
1Mo 1,1 I love you. ||| 1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. ||| 1Mo 1,2 Ich mag dich.
Hi 1,3 I am hungry. ||| Hi 1,3 Ich habe Durst.
Hi 1,4 I am foolish. ||| Hi 1,4 Ich bin neu.
Eu tentei o paste
comando como:
paste -d "|||" fileA fileB
Mas a saída retornada contém apenas um canal, como:
1Mo 1,1 I love you. |1Mo 1,1 Ich liebe dich.
1Mo 1,2 I like you. |1Mo 1,2 Ich mag dich.
Existe alguma maneira de separar cada par de linhas por tubo de tripa |||
?
text-processing
sed
awk
Olhar severo
fonte
fonte
paste -d '|||' fileA - - fileB < /dev/null
Respostas:
Com a pasta POSIX :
paste
concatenará as linhas correspondentes de todos os arquivos de entrada. Aqui temos seis arquivosfileA
, quatro arquivos fictícios do padrão em-
, efileB
.A lista de delimitadores inclui um espaço, três tubos e um espaço nessa ordem que serão usados por
paste
circularmente.Para a primeira linha de seis arquivos,
fileA
será concatenada com o primeiro arquivo fictício (o que não é nada, graças ao no -op: operador :), produzline1-fileA<space>
.O primeiro arquivo fictício será concatenado com o segundo por um pipe, produza
line1-fileA |
, e o segundo arquivo fictício com o terceiro arquivo fictício, produziráline1-fileA ||
, o terceiro arquivo fictício com o quarto arquivo fictício, produziráline1-fileA |||
.E o quarto arquivo fictício com
fileB
, produzline1-fileA ||| line1-fileB
.Essas etapas serão repetidas para todas as linhas, fornecendo o resultado esperado.
O uso de
:|
é para menos digitação e, principalmente, no shell interativo. Em um script, você deve usar:para impedir que um subshell seja gerado.
fonte
:|
. alternativa inteligente para</dev/null
- - - -
, mas da próxima vez que você pode até escrever um par de linhas para explicação :):|paste -d '|' fileA - - fileB
fornece a versão mais correta sem o delimitador de espaço.Bem, isso não usa sed, awk ou grep, mas você pode fazer isso facilmente no bash. O comando é:
O problema com a pasta é que o delimitador é um único caractere. Você também pode inserir um único caractere e o uso de sed para transformá-lo, mas isso pode ser passível de erro se o caractere já aparecer no arquivo de entrada.
fonte
IFS=
antes de cada umread
. Você pode fazer isso facilmente compaste
. Veja minha resposta e também esta para ver por que evitar o uso dewhile
loop no shell script.Uma versão do awk (GNU)
Com o
getline
comando inawk
, é possível definir$0
(todas as variáveis para colunas) do próximo registro de entrada, segetline < "filename"
você definir o próximo$0
no arquivo especificado.Por que sua tentativa não funcionou como o esperado? De
man paste
nós podemos lermas usa os delimitadores um para cada coluna .
Então o comando
paste -d '|*|*' fileA fileB fileA fileB
me dá linhas comoUma
sed
solução que sugiro evitar, mesmo que próxima à sua tentativa original, porque corrige o comportamento obtido para o seu objetivo original:Para evitar porque você substitui cada padrão
|
pelo novo|||
, mas você deve assumir que o símbolo de barra vertical (|
) não está presente nos seus dados ; caso contrário, você deve lidar com casos especiais e tornar o código mais complexo para evitar efeitos colaterais.Uma variante com a construção Here String [ 1 ]
<<<
Você define 5 delimitadores com
-d ' ||| '
(espaço, |, |, |, espaço) e 4 arquivos fictícios (- - - -
) que coletam dados da sequência vazia''
.Testado no GNU Awk 4.0.1, cole (GNU coreutils) 8.21 e sed (GNU sed) 4.2.2
fonte
sed
exemplo para evitar (:-)) e mais comentários.Se você quiser evitar a magia e o drama de delimitadores circulares e arquivos fictícios, basta anexar seu delimitador a um arquivo antes de colá-los:
dá
fonte
você pode fazer isso em python também dessa maneira.
fonte