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 queold
é 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