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