Um par de abordagens de perl:
$ perl -F_ -lae 'print $F[1]' file
ASSET-D
STRING-H
FILE-FD
O -a faz o perl agir como awk, dividindo cada linha de entrada no caractere dado por -F e salvando cada campo resultante na matriz @F . Portanto, imprimir $F[1] imprimirá o segundo campo (as matrizes começam a contar em 0).
Alternativamente:
$ perl -pe 's/.*?_(.+?)_.*//' file
ASSET-D
STRING-H
FILE-FD
O -p significa "imprimir todas as linhas de entrada depois de executar o script dado por -e sobre ele". O s/from/to/ é o operador de substituição. Ele substituirá from por to . Aqui, eu estou combinando 0 ou mais caracteres ( .* ), mas tornando-o "não-ganancioso" ( .*? ); que ? faz com que pare no menor tempo possível. Portanto, .*?_ corresponderá a todos até o primeiro _ . A próxima parte, (.+?)_ , corresponde a um ou mais caracteres até o próximo _ e depois combinamos todo o resto até o final da linha ( .* ). Os parênteses "capturam" a correspondência e a disponibilizam no lado de substituição do operador como . Portanto, a coisa toda apenas substituirá a linha inteira pelo que estiver dentro dos parênteses.
Você também pode fazer isso com grep :
$ grep -oP '^.*?_\K[^_]+' file
ASSET-D
STRING-H
FILE-FD
O -o significa "imprimir apenas a parte de cada linha que correspondeu" e o -P ativa as Expressões Regulares Compatíveis com Perl (PCRE) que nos fornecem \K . O \K , por sua vez, significa "ignorar tudo combinado até este ponto". Isso significa que podemos usar o ^.*?_ para processar tudo até o primeiro _ e, em seguida, usar \K para descartá-lo para que não seja impresso. Então, precisamos apenas de quantos caracteres não- _ , como podemos encontrar ( [^_]+ ).