Seria melhor usar uma ferramenta de processamento de texto padrão em vez de uma ferramenta ingênua como cut
.
Aqui estão algumas maneiras:
Com awk
, a obtenção do _
ou .
separou o segundo último campo:
awk -F '[_.]' '{print $(NF-1)}' file.txt
grep
com PCRE ( -P
):
grep -Po '\d+(?=[^_]*$)' file.txt
-
-o
obtém apenas a parte correspondente
-
\d+
corresponde a um ou mais dígitos
-
A antecipação positiva da largura zero, (?=[^_]*$)
, garante que nenhum _
esteja seguindo até o final da linha
com sed
:
sed -E 's/.*_([[:digit:]]+).*//' file.txt
-
.*_
corresponde a tudo até o último _
-
([[:digit:]]+)
corresponde aos dígitos necessários e coloca no grupo capturado
-
.*
corresponde ao restante
-
Na substituição, somente o grupo capturado,
, é usado
Com perl
, mesma lógica para o sed
one:
perl -pe 's/.*_(\d+).*/$1/' file.txt
Se você precisar usar cut
, faça isso em duas etapas, primeiro obtenha o quarto campo _
separado e, em seguida, obtenha o primeiro campo .
:
cut -d_ -f4 file.txt | cut -d. -f1
Isso não é recomendado, pois isso exige que os números dos campos sejam codificados.
Se fosse uma string, eu faria isso usando a expansão de parâmetros do shell:
% str='1.raw_bank_details_211.trg'
% str=${str##*_}
% echo "${str%%.*}"
211
Você ainda pode usar uma construção while
e usar cada linha em uma variável e fazer isso, mas isso seria lento para um arquivo grande. Você também pode usar alternadamente _.
como IFS
e obter o campo codificado (como cut
), se desejar.
Exemplo:
% cat file.txt
1.raw_bank_details_211.trg
2.raw_bank_details_222.trg
% awk -F '[_.]' '{print $(NF-1)}' file.txt
211
222
% grep -Po '\d+(?=[^_]*$)' file.txt
211
222
% sed -E 's/.*_([[:digit:]]+).*//' file.txt
211
222
% perl -pe 's/.*_(\d+).*/$1/' file.txt
211
222
% cut -d_ -f4 file.txt | cut -d. -f1
211
222