Suponha que eu tenha a string 1:2:3:4:5
e queira obter seu último campo ( 5
neste caso). Como faço isso usando o Bash? Eu tentei cut
, mas não sei como especificar o último campo com -f
.
293
Você pode usar operadores de string :
$ foo=1:2:3:4:5
$ echo ${foo##*:}
5
Isso apara tudo, desde a frente até um ':', avidamente.
${foo <-- from variable foo
## <-- greedy front trim
* <-- matches anything
: <-- until the last ':'
}
5
se a sequência for1:2:3:4:5:
(enquanto estiver usando os operadores de sequência produzirá um resultado vazio). Isso é especialmente útil ao analisar caminhos que podem conter (ou não) um/
caractere final .${foo%:*}
.#
- do começo;%
- do fim.#
,%
- menor correspondência;##
,%%
- partida mais longa.echo ${pwd##*/}
não funciona.pwd
como uma variável. Tentedir=$(pwd); echo ${dir##*/}
. Funciona para mim!Outra maneira é reverter antes e depois
cut
:Isso torna muito fácil obter o último, mas um campo, ou qualquer intervalo de campos numerados a partir do final.
fonte
echo "1 2 3 4" | rev | cut -d " " -f1 | rev
rev
, era exatamente o que eu precisava!cut -b20- | rev | cut -b10- | rev
É difícil obter o último campo usando o cut, mas aqui estão algumas soluções em awk e perl
fonte
/
caractere de acabamento :/a/b/c/d
e/a/b/c/d/
produz o mesmo resultado (d
) ao processarpwd | awk -F/ '{print $NF}'
. A resposta aceita resulta em um resultado vazio no caso de/a/b/c/d/
/
como delimitador e, se o seu caminho for,/my/path/dir/
ele usará o valor após o último delimitador, que é simplesmente uma string vazia. Portanto, é melhor evitar a barra se precisar fazer uma coisa como eu.awk '{$NF=""; print $0}' FS=: OFS=:
muitas vezes funciona bem o suficiente.Supondo um uso bastante simples (sem escape do delimitador, por exemplo), você pode usar grep:
Divisão - encontre todos os caracteres que não sejam o delimitador ([^:]) no final da linha ($). -o imprime apenas a parte correspondente.
fonte
Mão única:
Outro, usando uma matriz:
Ainda outro com uma matriz:
Usando expressões regulares do Bash (versão> = 3.2):
fonte
Simplesmente traduza o delimitador em uma nova linha e escolha a última entrada com
tail -1
.fonte
\n
, mas na maioria dos casos é a solução mais legível.Usando
sed
:fonte
Se seu último campo for um único caractere, você poderá fazer o seguinte:
Verifique a manipulação de strings no bash .
fonte
a
, não o último campo .Há muitas boas respostas aqui, mas ainda quero compartilhar esta usando o nome de base :
No entanto, ele falhará se já houver algum '/' na sua string . Se slash / é o seu delimitador, é necessário (e deve) usar o nome da base.
Não é a melhor resposta, mas apenas mostra como você pode ser criativo usando os comandos do bash.
fonte
Usando o Bash.
fonte
echo ${!#}
vez deeval echo \$${#}
.Primeiro, use xargs e divida-o usando ":", - n1 significa que cada linha possui apenas uma parte. Em seguida, pressione a última parte.
fonte
fonte
Para aqueles que se sentem confortáveis com o Python, https://github.com/Russell91/pythonpy é uma boa opção para resolver este problema.
Desde a ajuda pythonpy:
-x treat each row of stdin as x
.Com essa ferramenta, é fácil escrever código python que é aplicado à entrada.
fonte
Pode ser que seja um pouco tarde com a resposta, embora uma solução simples seja reverter a ordem da sequência de entrada. Isso permitiria que você sempre ganhasse o último item, independentemente do comprimento.
É importante observar que, se você usar esse método e os números forem maiores que 1 dígito (ou maiores que um caractere em qualquer circunstância), será necessário executar outro comando 'rev' sobre a saída canalizada.
Espero poder ajudar, felicidades
fonte
Uma solução usando a leitura incorporada:
Ou, para torná-lo mais genérico:
fonte
Se você gosta de python e tem uma opção para instalar um pacote, pode usar este utilitário python .
fonte
echo "1:2:3:4:5" | python -c "import sys; print(list(sys.stdin)[0].split(':')[-1])"
pythonp
pacote é fazer com que você faça as mesmas coisas quepython -c
com menos tipos de caracteres. Por favor, dê uma olhada no README no repositório.A correspondência de regex em
sed
é gananciosa (sempre vai para a última ocorrência), que você pode usar para sua vantagem aqui:fonte