Deseja extrair parte de um nome de arquivo antes do quinto _?

1

Eu tenho um arquivo abc_asdfjhdsf_ckd_dfksfj_c_12345678_223344.txt . Eu quero a saída como abc_asdfjhdsf_ckd_dfksfj_c.txt .

    
por EDWIN J 18.10.2015 / 21:59

4 respostas

2

Usando sed

$ echo abc_* | sed -E 's/(([^_]*_){5}).*//; s/_$/.txt/'
abc_asdfjhdsf_ckd_dfksfj_c.txt

Como funciona:

  • s/(([^_]*_){5}).*//

    Isso captura o início do nome do arquivo, até o quinto _ , no grupo 1 e exclui o restante dele.

    Mais detalhadamente, os comandos substitutos do sed têm o formato s/old/new/ , em que old é uma expressão regular. No nosso caso, o regex ([^_]*_){5} corresponde às cinco primeiras partes. Colocamos essa regex em parens, (([^_]*_){5}) , para que as primeiras cinco partes sejam salvas no grupo 1, que podemos referenciar como . .* corresponde a tudo depois dos primeiros cinco grupos. Substituímos tudo isso apenas pelos cinco primeiros grupos, .

  • s/_$/.txt/

    Isso encontra o último _ restante e o substitui por .txt .

Usando o awk

$ echo abc_* | awk -F_ '{print $1,$2,$3,$4,$5 ".txt"}' OFS=_
abc_asdfjhdsf_ckd_dfksfj_c.txt

Isso usa _ como os separadores de campo de entrada e saída. Assim, é apenas uma questão de imprimir os primeiros cinco campos seguidos por .txt .

Abordagem alternativa: removendo as duas últimas partes

Os códigos acima mantêm as cinco primeiras partes e descartam o resto. Na amostra da questão, existem sete partes, nenhuma que contenha um período. Se esse é sempre o caso , então uma abordagem alternativa (hat tip: Costas) é remover as duas últimas partes:

$ echo abc_* | sed -E 's/(_[^_]*){2}\././'
abc_asdfjhdsf_ckd_dfksfj_c.txt
    
por 18.10.2015 / 22:15
1

Referindo-se à pergunta original, você deseja renomear o final do arquivo:

ls abc*
abc_asdfjhdsf_ckd_dfksfj_c_12345678_223344.csv

ls abc* | cut -d_ -f1-5 | awk '{print $1".txt";}'
abc_asdfjhdsf_ckd_dfksfj_c.txt
    
por 18.10.2015 / 22:11
1
for   f in ./*_*_*_*_*_?*.txt
do    [ -e "$f" ] &&
      printf %s.txt\n "${f%"${f#*_*_*_*_*_?}"}"
done
    
por 19.10.2015 / 11:08
0

Usando bash expansão de parâmetro :

for f in abc_*; do f="${f%_*}"; echo "${f%_*}.txt"; done

Saída:

abc_asdfjhdsf_ckd_dfksfj_c.txt

${f%_*} é um padrão de expansão de parâmetro que conterá o valor da variável f após remover tudo após o último _ (inclusive).

    
por 19.10.2015 / 01:06

Tags