Insere texto em linhas específicas de um arquivo?

4

Como pode inserir algum texto em linhas específicas de um arquivo? Qual é o método mais simples que posso usar? (bash, sed, awk?)

O que eu quero fazer, pode ser simples, mas não sei onde devo começar. Demora muito tempo para eu tentar fazer isso manualmente (eu tenho muitos arquivos que eu tenho que mudar para o Excel / Calc usar posteriormente).

Aqui está o meu exemplo de arquivo de entrada:

4.06
4.05
5.04
4.06
34.50
56.06
45.33
36.44

E eu quero algo assim (insira o texto antes das linhas 1 e 5):

Exp1    
4.06
4.05
5.04
4.06
Exp2
34.50
56.06
45.33
36.44

Como posso fazer isso?

    
por Armen 02.11.2013 / 18:31

4 respostas

6
awk 'NR==1{print "Exp1"}NR==5{print "Exp2"}1' file

1 no final significa {print} .

sed '1i\
Exp1
5i\
Exp2
' file

Se você deseja estendê-lo para mais números, awk torna isso fácil:

awk 'NR%4==1{print "Exp"++i}1' file

Com números diferentes, vamos apenas dizer sed não é a ferramenta certa para o trabalho. É possível, mas não é bonito.

Como uma curiosidade acadêmica, aqui está em sed:

sed '1{ 
    h
    s/^.*$/Exp0/
    x   
}
x
s/^4//
s/^3/4/
s/^2/3/
s/^1/2/
/^E/ { 
    s/$/|/
    :x
    s/0|/1/
    s/1|/2/
    s/2|/3/
    s/3|/4/
    s/4|/5/
    s/5|/6/
    s/6|/7/
    s/7|/8/
    s/8|/9/
    s/9|/|0/
    tx
    s/^Exp|/Exp1/
    p
    s/^/1/
}
x' file
    
por 02.11.2013 / 18:40
2

Se o número de pontos de dados (estou assumindo) em cada um dos seus experimentos (novamente, estou assumindo) é sempre 4, você pode usar este one-liner Perl:

perl -ple '$. % 4 == 1 and print "Exp", ++$i' your_file

Como funciona

  • A chave -p diz ao Perl para fazer o loop sobre o (s) arquivo (s) dado (s) linha por linha (por padrão) e imprime cada linha depois de executar qualquer código fornecido.
  • A opção -l informa ao Perl para anexar automaticamente uma nova linha (por padrão) a cada instrução print .
  • A chave -e informa ao Perl que o que vier depois é o código a ser executado (o código que será executado antes de cada linha do arquivo ser impressa).
  • A variável especial $. contém o número da linha atualmente sendo processado. Se esse número de linha for congruente com 1 módulo 4 ( $. % 4 = 1 ), significa que precisamos inserir Exp # antes dele.
  • Por isso, testamos $. % 4 == 1 e, se for verdade, imprimiremos Exp ++$i\n (onde \n foi adicionado pela opção -l ). Isso funciona porque uma variável indefinida recebe um valor de zero por Perl quando é usada pela primeira vez como um inteiro.

Para que funcione com vários arquivos

  • A variável $. não redefinirá seu valor se você estiver processando vários arquivos de uma só vez. Obviamente, isso não é o que você quer. Você pode contornar isso escrevendo explicitamente o loop implícito criado por -p no one-liner acima para que você possa manipular o bloco continue .

    perl -le '
        while(<>){
            $. % 4 == 1 and print "Exp ",++$i
        } continue {
            print;             # Print the current line
            if(eof){           # If the next line is the end-of-file
                close ARGV ;   # Close the current filehandle to reset $.
                $i = 0     ;   # Reset the experiment counter if you need
            }
        }
    ' list_of_your_files
    

Notas

  • Ambas as soluções acima imprimirão o (s) arquivo (s) modificado (s) na saída padrão. Para emular uma edição em vigor (por exemplo, editar os próprios arquivos), adicione uma opção -i :

    perl -pi -le '$. % 4 == 1 and print "Exp", ++$i' your_file
    
    • Proceda da mesma forma para a outra solução.
    • Certifique-se de não colocar outro comutador diretamente após -i , pois ele interpreta qualquer coisa depois dele como a extensão a ser usada para criar um arquivo de backup.

    • Eu recomendo que você teste sem -i primeiro e depois adicione se os resultados forem satisfatórios.

por 02.11.2013 / 18:38
0

Você não precisa de linguagens externas, alguns comandos padrão podem fazer o truque. Por exemplo, para inserir algo na linha 5 do origin.txt você poderia fazer:

tmpfile='mktemp'
head -n4 origin.txt > $tmpfile
echo "I'm line 5 now" >> $tmpfile
tail -n +5 origin.txt >> $tmpfile
mv $tmpfile origin.txt
    
por 20.02.2015 / 14:28
0

Eu encontrei essa pergunta procurando uma maneira de adicionar um símbolo de comentário (#) ao início de uma linha nomeada em um arquivo. Usando o exemplo acima e alguns outros eu encontrei este é o comando awk para imprimir algo em uma linha nomeada.

awk 'NR==1{print "#"$0; next}1' <file

O NR==1 é a linha a ser considerada.
print "#" é o que adicionar $0 insere em uma string contendo o resto da linha no número fornecido next diz para pular essa linha (depois de imprimi-lo, senão você pega duas vezes) e como mencionado acima, o 1 à direita insere o restante do arquivo.

Espero que ajude alguém

    
por 09.11.2018 / 16:25