Extrair substring com caractere em vez de posição

1

Eu recentemente entrei em scripts do Nautilus e, para o que estou escrevendo, eu precisaria extrair um substrong de um nome de arquivo. Meu problema é que eu encontrei toneladas de métodos para extrair uma substring baseada na posição de um caractere, e não em como encontrar um determinado caractere em minha string e extrair uma substring de ou até este personagem. cut -f1 -d "delimiter" funciona, mas cut só aceita um delimitador de 1 caractere. Talvez awk ? expr ?

EDIT:
Estou escrevendo em bash Eu esperaria em um arquivo chamado por exemplo

[email protected]

a ser renomeado para simplesmente

Any Series S01 E01 VOSTFR.avi'
    
por joH1 24.12.2015 / 22:05

4 respostas

7

Com shells POSIX:

string=whateverDELIMrestDELIMmore
before_first_DELIM=${string%%DELIM*}
before_last_DELIM=${string%DELIM*}
after_first_DELIM=${string#*DELIM}
after_last_DELIM=${string##*DELIM}
    
por 24.12.2015 / 23:33
1

Se você tivesse escrito como gostaria de usar esse script, eu seria capaz de dar uma resposta mais específica, mas acho que a linha a seguir pode ser suficiente para você se adaptar às suas necessidades.

$ echo "abcde" | awk '{print substr($0, index($0, "c"))}'
cde

Basta substituir o segundo argumento de index pelo caractere que você deseja.

    
por 24.12.2015 / 23:28
0

A expansão de parâmetros realmente funcionou.

echo ${1%.S??E*}|sed 's/\./ /'

ecoa o nome da série e altera pontos potenciais em espaços. Não funcionaria para nenhuma série (por exemplo, o Sr. Robot precisa de um ponto), mas já está perto o suficiente.

    
por 26.12.2015 / 18:02
0

Você forneceu apenas um exemplo. Mais seria legal!

[email protected]

Que você quer dividir:

  • Any Series
  • S01
  • E01
  • VOSTFR
  • avi

À primeira vista, isso não é muito diferente do problema de nomeação do pacote RPM, em que o primeiro campo (nome) pode conter o delimitador usado em outro lugar. No entanto, vou supor que você tenha um campo de formato fixo que você também queira dividir em dois campos.

Para isso, dividiria temporada + episódio :

IFS=';' episode=( $(echo "$FILENAME"|sed -E 's/(.+)\.(S[0-9]{2})(E[0-9]{2})\.([^\.]+)\..*\.([^\.]+)/;;;;/') )

Estou definindo o delimitador como ponto-e-vírgula para o escopo da atribuição e, em seguida, conectando a saída da regex a uma matriz bash, que terá cinco campos: ${episode[0]} .. ${episode[4]}

Eu não expandi os pontos de campo do nome do episódio para espaços. Nós provavelmente poderíamos fazer tudo de uma só vez, mas tratá-lo separadamente permite que você faça coisas como sublinhados ou adicionando complicações como procurar por .. no caso de Mr..Robot - > %código%. Simplesmente:

episode[0]="${episode[0]//./ }"

E mais complexo, preservando Mr. Robot onde significa uma abreviação como em " . ":

episode[0]="$(echo "${episode[0]}"|sed -E 's/\.([^\.])/ /g')"

Por fim, eu criaria um nome de arquivo de destino, usando a expansão de matriz para imprimir quatro campos do campo # 0 delimitados por espaços, depois por um período e, em seguida, pelo último campo:

TARGET="${episode[@]:0:4}.${episode[4]}"

Depois, é só passar Mr. Robot e FILENAME para TARGET , usando aspas para garantir:

mv "$FILENAME" "$TARGET"
    
por 21.05.2016 / 01:51