Como inserir a saída do comando diretamente em um arquivo antes de um padrão?

5

Esta questão e suas respostas mostram que o conteúdo de um arquivo existente (" processedFile ") pode ser inserido em outro arquivo existente (" receivingFile ") antes de um de seus padrão s dentro, tal que:

sed -i -e '/pattern/r processedFile' receivingFile

Às vezes, esse conteúdo pode resultar de uma unidade de comando anterior e ainda não está escrito.

Nesse ponto, é possível inserir o resultado da unidade de comando em receiveFile sem criar / gravar o processedFile?

Exemplo:

Digamos que pré-processamos someFile da seguinte maneira (lendo seu conteúdo a partir da quarta linha até o final do arquivo):

awk 'NR>3' someFile

Agora, sem gravar isso em um novo arquivo, queremos inseri-lo diretamente em receiveFile antes de um padrão tal que:

awk 'NR>3' someFile | <insertion commands>

PS: De preferência usando awk ou sed .

Com base na solicitação do @RomanPerekhrest,

someFile :

# random output
# random
11
0 0 0 23.259058 2.1756592 -1.2097659 -0.074128056 0.34343502 -0.017659865
0 0 0.05 51.091269 4.8520157 -0.0011590485 0.00096592555 0.0059719715 -0.050598505

Pré-processamento:

awk 'NR>3' someFile :

0 0 0 23.259058 2.1756592 -1.2097659 -0.074128056 0.34343502 -0.017659865
0 0 0.05 51.091269 4.8520157 -0.0011590485 0.00096592555 0.0059719715 -0.050598505

receiveFile :

stackExchange is the best.
pattern
Unix stackExchange is the best of the bests.
    
por KutalmisB 12.02.2018 / 19:01

3 respostas

4

Não sei dizer se é portável em todos os * NIX, dependendo da implementação. Está trabalhando no meu Linux Debian.

TL; DR: use /dev/stdin como arquivo incluído, que é a entrada do sed e receberá a saída do comando antes do pipe, como

awk 'NR>3' someFile | sed -i -e '/pattern/r /dev/stdin' receivingFile

Exemplo: conteúdo do arquivo de destino chamado receivingFile :

stackExchange is the best.
pattern
Unix stackExchange is the best of the bests.

Exemplo de entrada chamado someFile :

# random output
# random
11
0 0 0 23.259058 2.1756592 -1.2097659 -0.074128056 0.34343502 -0.017659865
0 0 0.05 51.091269 4.8520157 -0.0011590485 0.00096592555 0.0059719715 -0.050598505

Para inserir após o padrão:

awk 'NR>3' someFile | sed -e '/pattern/r /dev/stdin' receivingFile

Para inserir antes do padrão, reutilize o resposta vinculada por OP e dump para saída:

awk 'NR>3' someFile | sed -n -e '/pattern/r /dev/stdin' -e 1x -e '2,${x;p}' -e '${x;p}' receivingFile

Para fazer o que foi solicitado e também substituir o arquivo:

awk 'NR>3' someFile | sed -i -n -e '/pattern/r /dev/stdin' -e 1x -e '2,${x;p}' -e '${x;p}' receivingFile

Novo conteúdo de receiveFile:

stackExchange is the best.
0 0 0 23.259058 2.1756592 -1.2097659 -0.074128056 0.34343502 -0.017659865
0 0 0.05 51.091269 4.8520157 -0.0011590485 0.00096592555 0.0059719715 -0.050598505
pattern
Unix stackExchange is the best of the bests.

UPDATE : como observado por @don_crissti, isso não funciona se padrão for a última linha. Aqui está um outro comando, adaptado de sua resposta para a mesma questão ligada! Algum outro comando é necessário para acomodar a adição temporária (e a supressão por sed) da linha extra em branco. Estes dois funcionariam:

awk 'NR>3' someFile | sed -e '/pattern/{r/dev/stdin' -e 'N;:l;$!n;$!bl};${/^$/!{s/\n$//};//d}' receivingFile <(printf '\n') > receivingFile.new
mv receivingFile.new receivingFile

ou apenas (não precisando bash e deixando sed -i para manipular o arquivo final):

awk 'NR>3' someFile | { echo '' >> receivingFile; sed -i -e '/pattern/{r/dev/stdin' -e 'N;:l;$!n;$!bl};${/^$/!{s/\n$//};//d}' receivingFile ; }

Veja o resposta vinculada para o código sed dividido em linha.

    
por 12.02.2018 / 19:46
3

Use apenas ex , o formato de script com POSIX especificado de vi (que também é especificado por POSIX).

printf '%s\n' '/pattern/-r !awk "NR>3" somefile' x | ex receivingFile

Ou mais geralmente:

printf '%s\n' '/pattern/-r !somecommand' x | ex somefile
    
por 13.02.2018 / 00:36
1

Com sed (GNU sed) 4.4

sed -i '/pattern/{h;s/.*/awk "NR>3" somefile/e;p;x}' receivingFile
    
por 12.02.2018 / 20:54