Como excluir ou pegar textos específicos dentro de um arquivo

0

Linux Centos 6-64

File1.txt tem várias linhas neste formato:

/Text1/Text2/Text3:Text4

Como fazer para ter o arquivo Result.txt com todas as linhas da seguinte maneira?

Text2;Text4

PS: o : se transforma em ; .

Pensei em duas maneiras de fazer isso:

  1. Não há problema em excluir /Text1/ e excluir /Text3 e alterar : por ; .
  2. Ou leia o que está entre o segundo e o terceiro / como Text2 e leia o que está depois de : , que é Text4 e do ;Text4 .

Então, como resultado final, o arquivo Result.txt teria

Text2;Text4

De qualquer maneira funcionaria, melhor aquele que trabalha mais rápido.

PS: Os textos podem ter espaços, símbolos e pontos dentro, mas os separadores originais dos textos são sempre / / / : que não aparecem em nenhum outro lugar dentro dos textos.

Isso deve ser feito em todas as linhas de File.txt .

Arquivos:

File1.txt

/Soccer.Teacher/Michael.John/Group1:monday-friday - 14h to 16h
/Basketball.Teacher/Susana.Stevens/Group2:tuesday-thursday-3pm-to-5pm
/Tennis.Teacher/Josh.Karen/Group3:monday-wednesday-5pm_to_7pm

etc.

Result.txt a ser:

Michael.John:monday-friday - 14:00 to 16:00
Susana.Stevens:tuesday-thursday-3pm-to-5pm
Josh.Karen:monday-wednesday-5pm_to_7pm

etc.

    
por Joao 01.08.2018 / 01:00

3 respostas

1

The texts may have spaces, symbols and points inside, but the original separators from the texts are always / / / : which don't appear anywhere else inside the texts.

Não é verdade. Você deu um exemplo com 14:00 to 16:00 . Por um momento, vamos supor que seja verdade. Isso permite uma abordagem direta:

tr ':' '/' | cut -d '/' --output-delimiter=';' -f 3,5

tr unifica os delimitadores e, em seguida, cut seleciona os campos certos.

Notas:

  • --output-delimiter não é requerido pelo POSIX. Se o seu cut não suporta, esta é a alternativa:

    tr ':' '/' | cut -d '/' -f 3,5 | tr '/' ';'
    

    Note que não podemos usar tr ':' ';' como o primeiro comando no pipe (o que simplificaria o resto) porque você não garante que ; não apareça na entrada ( cut será confundido se faz).

  • cut recebe os campos 3 e 5 (não 2 e 4) porque tudo antes do primeiro separador já é o campo 1 (string vazia no seu caso).

No entanto, se apenas o primeiro : for um separador, o comando poderá ser:

sed 's|:|/|' | cut -d '/' --output-delimiter=';' -f 3,5

sed 's|:|/|' substituirá apenas a primeira ocorrência de : (em oposição a sed 's|:|/|g' , que é equivalente ao nosso tr ':' '/' original).

Caso você não esteja familiarizado com uma maneira padrão de usar esses filtros com arquivos, essa é a sintaxe correta (com sed e cut compatível com POSIX):

< File1.txt sed 's|:|/|' | cut -d '/' -f 3,5 | tr '/' ';' > Result.txt
    
por 01.08.2018 / 08:50
2

sed faz isso:

echo '/Text1/Text2/Text3:Text4' | sed -E 's/\/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+):([a-zA-Z0-9]+)/;/'
  • -E usa expressões regulares estendidas
  • \/ use o caractere de escape para spesific / char
  • ([a-zA-Z0-9]+) define vamos dizer região do padrão de palavras .
  • ; acessando a segunda e quarta partes da região.

de acordo com sua última edição:

sed -E 's/\/([^/]+)\/([^/]+)\/([^/:]+):([^/]+)$/;/' FileName
    
por 01.08.2018 / 06:35
1

Não é a solução mais curta / mais rápida, mas realiza o trabalho e é fácil de entender:

#!/bin/bash

while read -r line; do
    echo -n "$line" | cut -d "/" -f 3 | tr -d $'\n'
    echo -n ";"
    echo "$line" | cut -d ":" -f 2
done < "File1.txt"

-n para os dois primeiros echo s é importante, por isso é tudo em uma linha.

Como sua versão do cut não suporta -z , o | tr -d $'\n' é necessário para remover a nova linha do recorte.

    
por 01.08.2018 / 05:08

Tags