Respuestas:
Awk es una buena opción si tienes que lidiar con espacios en blanco finales porque se encargará de ti:
echo " word1 word2 " | awk '{print $1;}' # Prints "word1"
Sin embargo, Cut no se ocupará de esto:
echo " word1 word2 " | cut -f 1 -d " " # Prints nothing/whitespace
'cortar' aquí no imprime nada / espacio en blanco, porque lo primero antes de un espacio era otro espacio.
-F","para anular el separador de campo predeterminado (un espacio) con una coma.
No es necesario utilizar comandos externos. Bash en sí mismo puede hacer el trabajo. Suponiendo "word1 word2" que obtuvo de algún lugar y se almacenó en una variable, por ejemplo
$ string="word1 word2"
$ set -- $string
$ echo $1
word1
$ echo $2
word2
ahora puede asignar $ 1, o $ 2, etc. a otra variable si lo desea.
stdin. @Matt M. --significa stdin, por lo que $stringse pasa como stdin. stdinestá separada por un espacio en blanco en argumentos $1, $2, $3, etc. - al igual que cuando un Bash Evalúa programa argumentos (por ejemplo, comprobación $1, $2etc.), este enfoque se aprovecha de la tendencia de la cáscara para dividir el stdinen argumentos de forma automática, eliminando la necesidad de awko cut.
setestablece los argumentos del shell.
word1=$(IFS=" " ; set -- $string ; echo $1)Configure IFS para reconocer correctamente el espacio entre las palabras. Envuelva entre paréntesis para evitar golpear el contenido original de $ 1.
string="*". Sorpresa.
Creo que una forma eficiente es el uso de matrices 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
Además, puede leer directamente matrices en una tubería:
echo "word1 word2" | while read -a array; do echo "${array[0]}" ; done
echo " word1 word2 " | { read -a array ; echo ${array[0]} ; }
string="*". Sorpresa.
whilesintaxis para recuperar cada primera palabra en cada línea. De lo contrario, utilice el enfoque Boontawee Home. Además, tenga en cuenta que echo "${array[0]}"se ha citado para evitar la expansión como lo notó gniourf-gniourf.
echo "word1 word2 word3" | { read first rest ; echo $first ; }
Esto tiene la ventaja de que no utiliza comandos externos y deja intactas las variables $ 1, $ 2, etc.
$1, $2, …intactas es una característica extremadamente útil para escribir guiones!
Si está seguro de que no hay espacios iniciales, puede usar la sustitución de parámetros bash:
$ string="word1 word2"
$ echo ${string/%\ */}
word1
Cuidado con escapar del espacio único. Vea aquí para más ejemplos de patrones de sustitución. Si tiene bash> 3.0, también puede usar la coincidencia de expresiones regulares para hacer frente a los espacios iniciales: consulte aquí :
$ string=" word1 word2"
$ [[ ${string} =~ \ *([^\ ]*) ]]
$ echo ${BASH_REMATCH[1]}
word1
%% *Aquí hay otra solución que usa la expansión de parámetros de shell . Se ocupa de múltiples espacios después de la primera palabra. El manejo de espacios delante de la primera palabra requiere una expansión adicional.
string='word1 word2'
echo ${string%% *}
word1
string='word1 word2 '
echo ${string%% *}
word1
Las %%significa borrar la coincidencia más larga de *(un espacio seguido de cualquier número de cualesquiera otros caracteres) en el arrastre parte de string.
Me preguntaba cómo se midieron varias de las mejores respuestas en términos de velocidad. Probé lo siguiente:
1 @ mattbh
echo "..." | awk '{print $1;}'
2 @ ghostdog74's
string="..."; set -- $string; echo $1
3 @ boontawee-home's
echo "..." | { read -a array ; echo ${array[0]} ; }
y 4 @ boontawee-home's
echo "..." | { read first _ ; echo $first ; }
Los medí con el timeit de Python en un script Bash en un terminal Zsh en macOS, usando una cadena de prueba con 215 palabras de 5 letras. Hizo cada medición cinco veces (los resultados fueron todos para 100 bucles, el mejor de 3), y promediaron los 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")
Buen trabajo, votantes 👏 ¡Los votos (a partir de este escrito) coinciden con la velocidad de las soluciones!
read -ano es válido en el tablero).
echo "word1 word2" | cut -f 1 -d " "
cortar corta el primer campo (-f 1) de una lista de campos delimitados por la cadena "" (-d "")
read es tu amigo:
Si la cadena está en una variable:
string="word1 word2"
read -r first _ <<< "$string"
printf '%s\n' "$first"Si está trabajando en una tubería: primer caso: solo desea la primera palabra de la primera línea:
printf '%s\n' "word1 word2" "line2" | { read -r first _; printf '%s\n' "$first"; }
segundo caso: desea la primera palabra de cada línea:
printf '%s\n' "word1 word2" "worda wordb" | while read -r first _; do printf '%s\n' "$first"; doneEstos funcionan si hay espacios principales:
printf '%s\n' " word1 word2" | { read -r first _; printf '%s\n' "$first"; }
Estaba trabajando con un dispositivo incrustado que no tenía ni perl, awk ni python y lo hizo con sed en su lugar. Admite múltiples espacios antes de la primera palabra (que las soluciones cuty bashno manejaron).
VARIABLE=" first_word_with_spaces_before_and_after another_word "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'
Esto fue muy útil al buscar psidentificadores de proceso ya que las otras soluciones aquí que usan solo bash no pudieron eliminar los primeros espacios que se psusan para alinear.