Como copiar seletivamente os detalhes de um arquivo e colá-los em um novo arquivo?

11

Eu tenho um arquivo contendo meus detalhes pessoais (.txt). Como posso através do terminal copiar apenas alguns detalhes do arquivo e colocá-los em um novo arquivo .txt ?

Por exemplo, se este for o conteúdo do arquivo:

name : farah age : 23 phone number : 0123 education : degree

como posso copiar apenas a idade e o número de telefone e enviá-los para um novo arquivo .txt ?

    
por MsWanie 31.08.2011 / 17:39

5 respostas

7

Existem várias maneiras de fazer isso. Se o seu arquivo tiver alguma estrutura conhecida, você poderá usar grep . O comando grep procura em um arquivo por uma frase específica e retorna linhas que correspondam a essa frase. Então, se o seu arquivo se parece com

Name: Sally

Date of Birth: 7.31.76

Address: 1234 Main St.

SSN: 123-45-6789

você pode executar grep Name info.txt e ele retornará Name: Sally . Você pode, então, redirecionar a saída para outro arquivo. Então chamando

grep Name info.txt > info2.txt

irá mostrar a linha para o novo arquivo info2.txt. Se você quiser acrescentar novas linhas, você pode fazer

grep Address info.txt >> info2.txt

caso contrário, o arquivo será sobrescrito.

Você também pode aprender a usar um editor de texto de linha de comando como vim.

    
por Kris Harper 31.08.2011 / 17:59
2

Você pode usar grep para procurar um expressão regular em details.txt e redirecionar o resultado para o novo arquivo.

Se todas as linhas que você deseja copiar tiverem algo em comum, as outras linhas não podem ser usadas:

grep "string in common" details.txt > new.txt

Se não você terá que procurar por cada linha que você deseja copiar, ainda usando o grep, e anexá-los a new.txt usando >> em vez de > .

    
por danjjl 31.08.2011 / 17:57
1

Existem também editores que trabalham no terminal, por ex. nano, vi e emacs.

Se você estiver usando uma interface gráfica de usuário em sua máquina local e um terminal em uma máquina remota, você também pode usar o mouse para copiar e colar de uma janela / guia de terminal para uma segunda.

    
por elmicha 31.08.2011 / 21:07
1

Supondo que o arquivo de entrada details.txt contenha:

name: farah
age: 23
phone number: 0123
education: degree

você pode selecionar as linhas "nome" e "telefone" por meio de extensão grep e redirecionar a saída para o novo.txt:

grep -E "age:|phone number:" details.txt > new.txt

Isso produzirá o novo.txt com:

age: 23
phone number: 0123

Como funciona:

O Grep imprime apenas linhas combinadas. As opções -E permitiram a regexp estendida, o que lhe dá a possibilidade de usar | (alternativa). Lembre-se de citar o padrão inteiro, então | será interpretado pelo grep. Caso contrário, o shell tentará interpretar. Você não quer isso aqui.

    
por Michał Šrajer 02.09.2011 / 17:10
1

O arquivo que você mostrou tem todos os detalhes em uma linha:

name : farah age : 23 phone number : 0123 education : degree

Eu assumi que você pode codificar age : etc no comando, mas o texto seguinte irá variar, e que os detalhes podem não estar na ordem dada ou serem contíguos.

Você pode extrair partes da linha com grep ' -o flag. Isso imprime apenas a parte correspondente, em vez da linha inteira.

Se você quiser incluir as partes age : e phone number : , use o sinalizador -e para especificar várias correspondências ou alternâncias.

$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123

A expressão [^ ]* significa qualquer número de caracteres que não são um espaço, portanto, corresponde a caracteres após age : até o próximo espaço.

Substitua file pelo nome do arquivo que contém seus detalhes. Você pode escrever o novo arquivo redirecionando a saída para um novo arquivo com o operador > , assim:

grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile

Quando você fizer isso, você não verá nenhuma saída. Você deve verificar primeiro a saída e depois redirecionar.

Aqui está o exemplo com alternância. Usamos o sinalizador -E para informar grep para usar a regex estendida. A sintaxe é (pattern1|pattern2) - corresponde a pattern1 e / ou pattern2 . Se um for encontrado, será impresso (independentemente de o outro ser encontrado ou não). Agora estou usando + significando pelo menos um dos caracteres precedentes, em vez de * significando zero ou mais do caractere precedente. Nesse contexto, ambos funcionam igualmente bem.

$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23 
phone number : 0123 

Se você quiser omitir as partes age : e phone number: , poderá usar o sinalizador -P para solicitar que grep use expressões regulares compatíveis com Perl. Isso suporta a alternância e também uma maneira de corresponder ao texto após um determinado padrão:

$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123

Se você deseja formatar o texto de maneira diferente, use sed , por exemplo:

$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/: | :/' file
age:23 | phone number:0123

Isso depende de age vindo antes de phone number , portanto, ajuste de acordo se não for o caso. Se você não pode confiar no pedido, você pode usar este comando muito intrincado:

$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/ /; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/:  | : /' file
phone number: 0123 | age: 23

Isso reorganiza a linha para que a seção phone number : seja a primeira em todas as linhas e, em seguida, faça uma segunda substituição para selecionar os detalhes desejados. Eu devo a técnica usada aqui para responder por muru .

Notas sobre os comandos sed não cobertos por explicações anteriores

  • -r usa a regex estendida para comandos mais legíveis (o% GNUsed entende -E com o mesmo significado)
  • s/old/new/ replace old com new
  • (pattern) salva pattern para referência posterior, com ou etc (correspondente à ordem da esquerda para a direita em que os grupos de captura ocorrem - observe que sed conterá até 7 desses !).
  • . de qualquer caractere, portanto .* representa qualquer número de qualquer caractere.
  • ; separa os comandos, como no shell.
por Zanna 27.04.2018 / 19:43