Extrair campos no arquivo e armazená-lo em um arquivo diferente no vim

1

Eu tenho o arquivo int no seguinte formato:

.

.

.

Name:abc

Occupation:def

.

.

Name:xyz

Occupation:ghi

.

. 

Eu quero extrair o campo de nome e ocupação e salvá-lo em outro arquivo out.txt usando vim no seguinte formato:

Name:abc

Occupation:def

Name:def

Occupation:ghi

EDIT: Posição do campo de ocupação no arquivo de entrada atualizado

    
por user2179293 25.08.2013 / 17:27

4 respostas

2
ggyG:e out.txt<cr>p:v/Name\|Occupation/d<cr>:w<cr>

Explicação

gg # Go to beginning of file
y  # yank (copy)
G  # to end of file
:e out.txt # Open a new file called out.txt
p  # paste what you just copied
:v/Name\|Occupation/d # Delete all lines that don't contain Name or Occupation
:w # save
    
por 25.08.2013 / 17:58
1

Que tal você escrever seu vim buffer e sair ( :wq ) e usar isso:

grep -E '^(Name|Occupation)' your_file >out.txt

O comando grep imprimirá todas as linhas em your_file que correspondam ao padrão que fornecemos. O padrão usado aqui requer expressões regulares estendidas, e é por isso que estou usando a opção -E para grep . O padrão é o seguinte:

  • ^ significa início da linha
  • (Name|Occupation) significa procurar Name ou Occupation
  • Em conjunto, a expressão regular significa procurar linhas iniciando com a palavra Name ou linhas iniciando com a palavra Occupation .

Deixado sozinho, o comando grep teria imprimido todas as linhas correspondentes no terminal. O último bit ( >out.txt ) redireciona a saída do comando grep para o arquivo out.txt do terminal.

    
por 25.08.2013 / 18:05
1

VIM:

:g/\./d | sav /tmp/otherFileName

SED:

sed '/\(\.\)/d' InputFile >> /tmp/otherFileName

Mais perfeito:

:v/^Name*\|^Occupation*/d | s/^Name/\r&/g | sav /tmp/OtherFileName
    
por 25.08.2013 / 18:18
0

Fora do vim , que poderia ser usado para alcançar o resultado, há uma série de ferramentas de linha de comando que podem alcançar o mesmo resultado. Usando o perl como exemplo:

 perl -n -e '$name=$1 if(/^(Name: .+)$/); print "$name\n\n$_\n" if(/^Occupation: .+/);' < file > out.txt

perl -n diz ao perl para agrupar cada linha da entrada padrão ( STDIN ) em um loop while. Podemos redirecionar um arquivo para o STDIN se usarmos < file no final do comando perl.

Isso tem o efeito de permitir que você execute comandos perl em cada linha do file que redirecionamos.

Em seguida, especificamos quais comandos o perl deve executar com a opção -e , que seguimos:

'$name=$1 if(/^(Name: .+)$/); print "$name\n\n$_\n" if(/^Occupation: .+/);'

(observe as aspas simples ' em torno das instruções perl, pois o perl precisa da opção -e como um único argumento na linha de comando).

Quanto à lógica do código,

 $name=$1 if(/^(Name: .+)$/);

se uma linha começar ^ com Name: seguido por um ou mais caracteres .+ e, em seguida, o final da linha $ , poderemos armazenar toda essa correspondência se a envolvermos em () e ele ficará disponível em uma variável especial chamada $1 . Portanto, todo Name: whatever é armazenado em $1 . Em seguida, atribuímos isso a uma variável chamada $name .

Semelhante à instrução anterior, fazemos o seguinte:

 print "$name\n\n$_\n" if(/^Occupation: .+/);'

se uma linha começar ^ com Occupation: seguido por um ou mais caracteres .+ e, em seguida, o final da linha $ , imprima a linha de nome correspondida anteriormente (armazenada em $ name), duas novas linhas \n\n e, em seguida, $_ , que é o conteúdo da linha atual que o loop while está processando (no nosso caso, a linha de ocupação do jogo), seguida por outra nova linha de linha \n ;

Finalmente, redirecionamos a saída desse comando para out.txt com > out.txt .

Existe uma suposição de que cada Name: é seguido (algumas linhas depois) com uma Ocupação relacionada a esse Name: , se você tiver várias linhas de Ocupação, então você imprimirá mais de um nome e ocupação. Além disso, se o nome não tiver uma linha de ocupação, ele não será impresso.

    
por 25.08.2013 / 18:01