Redirecionando a saída de impressão para vários arquivos no awk

Redirecionando a saída de impressão para vários arquivos no awk

Quero imprimir as mesmas linhas em 2 arquivos diferentes. O que estou fazendo agora é:

print ID[i]" "Value[i]" "TS1[i]" "TS2[i] > "file1.txt";
print ID[i]" "Value[i]" "TS1[i]" "TS2[i] > "file2.txt";

Posso escrever um único comando para redirecioná-lo para dois arquivos diferentes?

EDITAR

Não quero imprimir toda a saída do meu comando em vários arquivos, quero escrever alguns registros com base em alguma condição em vários arquivos. Estou imprimindo isso dentro do awkscript, então preciso de umeficientemaneira de fazer isso.

Responder1

Você não pode fazer isso com awk.

Usando tee, você pode fazer algo assim:

$ awk '{print ID[i]" "Value[i]" "TS1[i]" "TS2[i]}' file | tee out1 out2

Usando tee -ase você deseja anexar em vez de substituir arquivos existentes.

Se não quiser imprimir toda a saída, você pode tentar:

awk '
    BEGIN {outfile["a.txt"];outfile["b.txt"]}
    { for (file in outfile) { print > file } }' file

Responder2

Dentro awk, em vez de redirecionar para um arquivo com print "text" > "file", você pode redirecionar para um comando usando:

print "something" | "tee file1.txt file2.txt"

A primeira vez que você usa isso |, awkgera o comando, e na próxima vez ele reutiliza o mesmo comando, então ele não inicia um novo teecada vez que você faz isso e não sobrescreve os arquivos (você precisa ligar close("tee file1.txt file2.txt")se quiser awkpara iniciar um novo comando na próxima vez). No entanto, se você fizer as duas coisas > "file1.txt", | "tee file1.txt..."haverá um conflito.

Você pode querer usar >> "file1.txt"e | "tee -a file1.txt..."em vez disso.

No entanto, eu ainda iria comforAbordagem de @cuonglmou use uma awkfunção, pois seria mais limpa e eficiente.

Responder3

Afunção definida pelo usuáriopode tornar seu código mais limpo e causar menos duplicação, se essa for a preocupação.

function print_to_files( message, file_a, file_b ) {
   print message > file_a;
   print message > file_b;
}

message = sprintf( "%s %s %s %s", ID[i], Value[i], TS1[i], TS2[i] )
print_to_files( message , "filea", "fileb" );'

Ou codifique os arquivos se isso for tudo que você precisa.

function print_to_files( message ) {
   print message > "/path/to/filea";
   print message > "/path/to/fileb";
}

message = sprintf( "%s %s %s %s", ID[i], Value[i], TS1[i], TS2[i] )
print_to_files( message );'

Responder4

Você pode fazer isso sed- mas sem uma ideia mais clara de sua opinião, não sei como demonstrá-la especificamente. Ainda assim, aqui está um exemplo genérico:

seq 10 | sed -ne '/1/w ./onesfile.txt' -e '/3/w threesfile.txt'

Isso grava apenas as linhas que contêm a 1to the onesfile.txte for 3- todo o resto é excluído. Isto é ummuitoexemplo básico de como isso pode funcionar, mas se você pudesse fornecer um exemplo de entrada, eu poderia fazer um pouco melhor.

Uma vez sedaberto um arquivo para gravação, ele permanece aberto até que o processo seja concluído - ele não trunca continuamente suas próprias gravações - os descritores de arquivo são retidos durante a vida do processo.

informação relacionada