Eu tenho uma string:
one_two_three_four_five
Preciso salvar em um A
valor variável two
e em B
valor variável four
da string acima
Use cut
com _
como delimitador de campo e obtenha os campos desejados:
A="$(cut -d'_' -f2 <<<'one_two_three_four_five')"
B="$(cut -d'_' -f4 <<<'one_two_three_four_five')"
Você também pode usar echo
e canalizar em vez da cadeia Here:
A="$(echo 'one_two_three_four_five' | cut -d'_' -f2)"
B="$(echo 'one_two_three_four_five' | cut -d'_' -f4)"
Exemplo:
$ s='one_two_three_four_five'
$ A="$(cut -d'_' -f2 <<<"$s")"
$ echo "$A"
two
$ B="$(cut -d'_' -f4 <<<"$s")"
$ echo "$B"
four
$ echo $FILE
my_user/my_folder/file.csv
$ A="$(cut -d'/' -f2 <<<"$FILE")"
$ echo $A
[file]*
Você sabe o que está acontecendo aqui?echo "${s##*_}"
Usando apenas construções sh POSIX, é possível usar construções de substituição de parâmetro para analisar um delimitador por vez. Observe que esse código pressupõe que haja o número necessário de campos, caso contrário, o último campo será repetido.
Como alternativa, você pode usar uma substituição de parâmetro sem aspas com a expansão de curinga desativada e
IFS
configurada para o caractere delimitador (isso só funciona se o delimitador for um caractere não-espaço em branco único ou se qualquer sequência de espaço em branco for um delimitador).Isso derruba os parâmetros posicionais. Se você fizer isso em uma função, apenas os parâmetros posicionais da função serão afetados.
Ainda outra abordagem é usar o
read
builtin.fonte
unset IFS
não retornaIFS
ao padrão. Se depois disso alguémOldIFS="$IFS"
tiver um valor nulo no OldIFS. Além disso, supõe-se que o valor anterior do IFS seja o padrão, o que é muito possível (e útil) não ser. A única solução correta é armazenarold="$IFS"
e restaurar posteriormente com IFS = "$ old". Ou ... use um sub-shell(...)
. Ou, melhor ainda, leia minha resposta.unset IFS
não restauraIFS
o valor padrão, mas retorna a divisão do campo para o efeito padrão. Sim, é uma limitação, mas geralmente aceitável na prática. O problema com um subshell é que precisamos extrair dados dele. Eu mostro uma solução que não muda o estado no final, comread
. (Ele funciona em shells POSIX, mas o IIRC não no shell Bourne porque executaria oread
subshell devido ao documento aqui.) Usar<<<
como na resposta é uma variante que funciona apenas em ksh / bash / zsh.user/my_folder/[this_is_my_file]*
? O que eu obtenho quando sigo essas etapas é[this_is_my_file]*
/
.Queria ver uma
awk
resposta, então aqui está uma:fonte
awk -F_ '{print $NF}' <<< 'one_two_3_4_five'
A maneira mais simples (para cascas com <<<) é:
Usando uma variável temporal em
$a
vez de$_
porque um shell reclama.Em um script completo:
Nenhuma alteração do IFS, nenhum problema com
set -f
(expansão do nome do caminho) Nenhuma alteração nos parâmetros posicionais ("$ @").Para uma solução portátil para todos os shells (sim, todos os POSIX incluídos) sem alterar o IFS ou
set -f
, use o (um pouco mais complexo) equivalente heredoc:Entenda que essas soluções (tanto o documento em questão quanto o uso de
<<<
removerão todas as novas linhas finais.E isso foi desenvolvido para um conteúdo variável de "uma linha". As
soluções para várias linhas são possíveis, mas precisam de construções mais complexas.
Uma solução muito simples é possível na versão 4.4 do bash
Não há equivalente para shells POSIX, pois muitos shells POSIX não possuem matrizes.
Para shells com matrizes pode ser tão simples quanto:
(testado trabalhando em attsh, lksh, mksh, ksh e bash)
Mas com muito encanamento adicional para manter e redefinir variáveis e opções:
No zsh, as matrizes começam em 1 e não dividem a string por padrão.
Portanto, algumas alterações precisam ser feitas para que isso funcione no zsh.
fonte
read
são simples, desde que OP não quer extrair a 76 e os elementos 127 a partir de uma longa seqüência ...readarray
poderia ser mais fácil de usar para essa situação.Com
zsh
você pode dividir a string (ativada_
) em uma matriz:e acesse cada elemento / qualquer via índice de matriz:
Tenha em mente que em
zsh
(ao contrárioksh
/bash
) índices de matriz começam em 1 .fonte
set -f
aviso à primeira solução. ... asteriscos,*
talvez?set -f
? Eu não estou usandoread
/IFS
. Tente minhas soluções com uma string como*_*_*
ou o que quer ...É permitida uma solução python?
fonte
Outro exemplo estranho; mais simples de entender.
Também pode ser usado com variáveis.
Suponha:
this_str = "one_two_three_four_five"
Então o seguinte funciona:
A = `echo $ {this_str} | awk -F_ '{print $ 1}' '
B = `eco $ {this_str} | awk -F_ '{print $ 2}' '
C = `eco $ {this_str} | awk -F_ '{print $ 3}' '
... e assim por diante ...
fonte