File1
conteúdo:
line1-file1 "1"
line2-file1 "2"
line3-file1 "3"
line4-file1 "4"
File2
conteúdo:
line1-file2 "25"
line2-file2 "24"
Pointer-file2 "23"
line4-file2 "22"
line5-file2 "21"
Após a execução do script perl / shell, o File2
conteúdo deve se tornar:
line1-file2 "25"
line2-file2 "24"
line1-file1 "1"
line2-file1 "2"
line3-file1 "3"
line4-file1 "4"
Pointer-file2 "23"
line4-file2 "22"
line5-file2 "21"
ou seja, cole o conteúdo de File1
in File2
antes da linha que contém "Ponteiro".
text-processing
awk
sed
perl
user1228191
fonte
fonte
Respostas:
sed
tem uma função para isso e pode fazer a modificação em linha:Mas isso coloca sua linha de ponteiro acima do arquivo1. Para colocá-lo abaixo, retarde a saída da linha:
fonte
-e 1x -e '2,${x;p}' -e '${x;p}'
fazer? Entendo que você troca coisas no buffer de padrão e depois imprime, mas não sei o que nem por que você adicionou a opção silenciosa-n
no início.Sem usar
sed
ouawk
...Primeiro, encontre a linha na qual está o seu padrão:
Em seguida, use 3 comandos para gerar o resultado desejado:
Isto tem a desvantagem de acessar 3 vezes o arquivo
file2
, mas pode ser mais claro do que ased
deawk
solução.fonte
awk
torna isso bastante fácil.Insira a linha antes do arquivo:
Para imprimir o arquivo interno após a
Pointer
linha, basta alternar a ordem dos padrões (você precisa adicionar um ponto-e-vírgula para obter a ação padrão) e soltar aline
variável:E só porque ninguém usou
perl
ainda,fonte
system("cat innerfile")
envia oinnerfile
para o console. Estou esquecendo de algo?Um trabalho fácil para
ed
:-r file1
lê no arquivo especificado para depois da linha endereçada, que neste caso é a linha anterior à primeira linha correspondentePointer
. Portanto, isso inserirá o conteúdo defile2
apenas uma vez, mesmo quePointer
ocorra em várias linhas. Se você deseja inseri-lo antes de cada linha correspondente, adicioneg
flag lobal:Substitua
,p
porw
se desejar editar o arquivo no local.A
sed
resposta aceita funciona na maioria dos casos, mas se o marcador estiver na última linha, o comando não funcionará conforme o esperado: ele inserirá o conteúdoFile1
após o marcador.Eu tentei inicialmente com:
que também funciona bem (como
r
fará sua mágica no final do ciclo), mas tem o mesmo problema se o marcador estiver na última linha (não háN
linha ext após a última linha). Para contornar isso, você pode adicionar uma nova linha à sua entrada:Isso inserirá o
file2
conteúdo antes de cada linha correspondente. Para inseri-lo somente antes da primeira linha correspondente, você pode usarl
oop e puxar an
linha ext até chegar ao final do arquivo:Com essas
sed
soluções, você perde a capacidade de editar no local (mas pode redirecionar para outro arquivo).fonte
Use um loop para ler as linhas no arquivo2. Se você encontrar uma linha começando com
Pointer
, imprima o arquivo1. Isso é mostrado abaixo:fonte
Existem algumas maneiras de resolver esse problema
sed
. Uma maneira é uma leitura atrasada, conforme recomendado na resposta aceita. Também poderia ser escrito como:... com um olhar explícito e pouco explícito, em vez do olhar para trás implementado em outro lugar com o buffer de espera. Isso inevitavelmente terá o mesmo problema com a última linha que o @don_crissti observa, porque
N
faz incremento do ciclo de linha eor
comando ead é aplicada por número da linha.Você pode contornar isso:
Nem todos os
sed
s interpretam o-
significado de entrada padrão, mas muitos o fazem. ( POSIX diz quesed
deve apoiar-
deve significar entrada padrão se o implementador quiser-
significar entrada padrão ???)Outra maneira é manipular o conteúdo anexado em ordem. Há outro comando que agenda a saída da mesma maneira que o
r
ead faz, esed
o aplicará er
na ordem em que estão no script. No entanto, é um pouco mais complicado - implica o uso de umsed
paraa
pendurar aPointer
correspondência na saída de outrosed
em seu script.Então, basicamente, o primeiro
sed
escreve o segundo,sed
um script, que o segundosed
lê na entrada padrão (talvez ...) e se aplica por sua vez. O primeirosed
funciona apenas na primeira correspondência paraPointer
encontrado e, depois,q
utiliza a entrada. Seu trabalho é ...s/[]^$&\./*[]/\\&/g;H
sed
precisará interpretar cada parte que lê literalmente para acertar. Feito isso, coloque uma cópia noH
espaço antigo.s|.*|/&/!p;//!d|p; x
sed
para criarp
todas as linhas de entrada,!
exceto a/&/
que acabamos de proteger; e depoisd
excluir tudo da mesma forma.p
rint os comandos no segundo esed
, em seguida, ex
altere osh
buffers antigo e padrão para trabalhar em nossa cópia salva.s|.|r file1&a\\&|p;q
\n
ewline, porque elesed
será anexado quando oH
campo for delimitado anteriormente. Então, inserimos o comandor file1
e o seguimos com nosso\n
ewline, depois o comandoa\\
paraa
ppend seguido também por um\n
ewline. Todo o resto da nossaH
linha de campo segue a última linha de\n
ew.O script que o primeiro escreve é mais ou menos assim:
Basicamente, o segundo
sed
imprime todas as linhas, mas a primeirased
configura-a comoa
pendente. Para essa linha específica, estão programadas duas gravações atrasadas na saída padrão - a primeira é ar
ead defile1
eo segundo é uma cópia da linha queremos depois. O primeirosed
médico não é necessário neste caso consulta (veja? Sem barras invertidas), mas é importante escapar com segurança da maneira que faço aqui sempre que uma correspondência de padrão é redirecionada como entrada.Enfim, então ... existem algumas maneiras.
fonte
Isso é bastante simples com o AWK:
Arquivo1 no Arquivo2 antes do padrão = "Ponteiro"
Primeiro carregue o conteúdo do Arquivo1 em uma variável
então faça a inserção
(Ou, se você deseja inserir Arquivo1 após "Ponteiro")
fonte
minha maneira preferida: modelagem .
Isso substituirá todas as ocorrências de CHANGEME no origfile pelo conteúdo de file2insert . Remova o último g do sed para substituir apenas a primeira ocorrência de CHANGEME .
fonte
$x
no seu primeiro comando, quando ele é definido apenas no seu segundo comando?[Inserir o conteúdo do arquivo em outro arquivo ANTES do padrão]
[Depois do padrão]
fonte
N
funciona bem, mas não se ofonte