Respostas:
O Awk é uma boa opção se você precisar lidar com espaços em branco à direita, porque ele cuidará disso para você:
echo " word1 word2 " | awk '{print $1;}' # Prints "word1"
O Cut não vai resolver isso:
echo " word1 word2 " | cut -f 1 -d " " # Prints nothing/whitespace
'cut' aqui não imprime nada / espaço em branco, porque a primeira coisa antes de um espaço era outro espaço.
-F","
substituir o separador de campo padrão (um espaço) por vírgula.
não há necessidade de usar comandos externos. O próprio Bash pode fazer o trabalho. Supondo que "word1 word2" você tenha obtido de algum lugar e armazenado em uma variável, por exemplo
$ string="word1 word2"
$ set -- $string
$ echo $1
word1
$ echo $2
word2
agora você pode atribuir $ 1 ou $ 2 etc a outra variável, se quiser.
stdin
. @Mat M. --
significa stdin
, então $string
está sendo passado como stdin
. stdin
é um espaço em branco-separados em argumentos $1
, $2
, $3
, etc. - assim como quando uma festança Avalia programa argumentos (por exemplo, cheque $1
, $2
etc.), esta abordagem tira proveito da tendência do shell para dividir o stdin
em argumentos automaticamente, eliminando a necessidade de awk
ou cut
.
set
define os argumentos do shell.
word1=$(IFS=" " ; set -- $string ; echo $1)
Defina o IFS para reconhecer corretamente o espaço entre as palavras. Coloque parênteses para evitar espantar o conteúdo original de $ 1.
string="*"
. Surpresa.
Eu acho que uma maneira eficiente é o uso de matrizes bash:
array=( $string ) # do not use quotes in order to allow word expansion
echo ${array[0]} # You can retrieve any word. Index runs from 0 to length-1
Além disso, você pode ler diretamente matrizes em uma linha de tubulação:
echo "word1 word2" | while read -a array; do echo "${array[0]}" ; done
echo " word1 word2 " | { read -a array ; echo ${array[0]} ; }
string="*"
. Surpresa.
while
sintaxe para recuperar cada primeira palavra em cada linha. Caso contrário, use a abordagem do Boontawee Home. Além disso, observe que echo "${array[0]}"
foi citado para impedir a expansão, conforme observado pelo gniourf-gniourf.
echo "word1 word2 word3" | { read first rest ; echo $first ; }
Isso tem a vantagem de não usar comandos externos e deixa intactas as variáveis $ 1, $ 2 etc.
$1, $2, …
intactas é um recurso extremamente útil para escrever scripts!
Se você tiver certeza de que não há espaços à esquerda, poderá usar a substituição do parâmetro bash:
$ string="word1 word2"
$ echo ${string/%\ */}
word1
Cuidado para escapar do espaço único. Veja aqui mais exemplos de padrões de substituição. Se você tem bash> 3.0, também pode usar correspondência de expressão regular para lidar com espaços à esquerda - veja aqui :
$ string=" word1 word2"
$ [[ ${string} =~ \ *([^\ ]*) ]]
$ echo ${BASH_REMATCH[1]}
word1
%% *
Aqui está outra solução usando a expansão de parâmetros do shell . Ele cuida de vários espaços após a primeira palavra. A manipulação de espaços na frente da primeira palavra requer uma expansão adicional.
string='word1 word2'
echo ${string%% *}
word1
string='word1 word2 '
echo ${string%% *}
word1
Os %%
significa eliminar a maior correspondência possível de *
(um espaço seguido por qualquer número de quaisquer outros caracteres) no arrasto parte string
.
Eu me perguntava como várias das principais respostas se comparam em termos de velocidade. Eu testei o seguinte:
1 @ mattbh's
echo "..." | awk '{print $1;}'
2 @ ghostdog74
string="..."; set -- $string; echo $1
3 @ boontawee-casa
echo "..." | { read -a array ; echo ${array[0]} ; }
e 4 @ boontawee-home's
echo "..." | { read first _ ; echo $first ; }
Eu os medi com o tempo do Python em um script Bash em um terminal Zsh no macOS, usando uma sequência de teste com 215 palavras de 5 letras. Realizou cada medição cinco vezes (os resultados foram todos para 100 voltas, melhor de 3) e calculou a média dos resultados:
method time
--------------------------------
1. awk 9.2ms
2. set 11.6ms (1.26 * "1")
3. read -a 11.7ms (1.27 * "1")
4. read 13.6ms (1.48 * "1")
Bom trabalho, eleitores 👏 Os votos (até o momento em que escrevemos) correspondem à velocidade das soluções!
read -a
é inválido no traço).
echo "word1 word2" | cut -f 1 -d " "
cut corta o 1º campo (-f 1) de uma lista de campos delimitados pela string "" (-d "")
read
é seu amigo:
Se a string estiver em uma variável:
string="word1 word2"
read -r first _ <<< "$string"
printf '%s\n' "$first"
Se você estiver trabalhando em um pipe: primeiro caso: você quer apenas a primeira palavra da primeira linha:
printf '%s\n' "word1 word2" "line2" | { read -r first _; printf '%s\n' "$first"; }
segundo caso: você quer a primeira palavra de cada linha:
printf '%s\n' "word1 word2" "worda wordb" | while read -r first _; do printf '%s\n' "$first"; done
Eles funcionam se houver espaços à esquerda:
printf '%s\n' " word1 word2" | { read -r first _; printf '%s\n' "$first"; }
Eu estava trabalhando com um dispositivo incorporado que não possuía perl, awk ou python e o fez com o sed. Ele suporta vários espaços antes da primeira palavra (que as soluções cut
e bash
não manipularam).
VARIABLE=" first_word_with_spaces_before_and_after another_word "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'
Isso foi muito útil quando grepping ps
para IDs de processo, pois as outras soluções aqui usando apenas o bash não conseguiram remover os primeiros espaços ps
usados para alinhar.