Risposte:
Awk è una buona opzione se hai a che fare con gli spazi vuoti finali perché se ne occuperà per te:
echo " word1 word2 " | awk '{print $1;}' # Prints "word1"
Cut non si prenderà cura di questo però:
echo " word1 word2 " | cut -f 1 -d " " # Prints nothing/whitespace
'cut' qui non stampa nulla / spazi bianchi, perché la prima cosa prima di uno spazio era un altro spazio.
-F","per sovrascrivere il separatore di campo predefinito (uno spazio) con una virgola.
non è necessario utilizzare comandi esterni. Bash stesso può fare il lavoro. Supponendo che "parola1 parola2" hai ricevuto da qualche parte e memorizzato in una variabile, ad es
$ string="word1 word2"
$ set -- $string
$ echo $1
word1
$ echo $2
word2
ora puoi assegnare $ 1 o $ 2 ecc. a un'altra variabile, se lo desideri.
stdin. @ Matt M. --significa stdin, quindi $stringviene passato come stdin. stdinè separate da spazi in argomenti $1, $2, $3, ecc - proprio come quando un colpo valuta programma argomenti (ad esempio controllo $1, $2ecc), questo approccio sfrutta tendenza della shell di dividere la stdinin argomenti automaticamente, eliminando la necessità di awko cut.
setimposta gli argomenti della shell.
word1=$(IFS=" " ; set -- $string ; echo $1)Imposta IFS per riconoscere correttamente lo spazio tra le parole. Metti tra parentesi per evitare di rovinare il contenuto originale di $ 1.
string="*". Sorpresa.
Penso che un modo efficiente sia l'uso di array 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
Inoltre, puoi leggere direttamente gli array in una pipe-line:
echo "word1 word2" | while read -a array; do echo "${array[0]}" ; done
echo " word1 word2 " | { read -a array ; echo ${array[0]} ; }
string="*". Sorpresa.
whilesintassi per recuperare ogni prima parola su ogni riga. Altrimenti, usa l'approccio Boontawee Home. Inoltre, tieni presente che echo "${array[0]}"è stato citato per prevenire l'espansione come notato da gniourf-gniourf.
echo "word1 word2 word3" | { read first rest ; echo $first ; }
Ciò ha il vantaggio di non utilizzare comandi esterni e di lasciare intatte le variabili $ 1, $ 2, ecc.
$1, $2, …intatte le variabili è una caratteristica estremamente utile per la scrittura di script!
Se sei sicuro che non ci siano spazi iniziali, puoi usare la sostituzione del parametro bash:
$ string="word1 word2"
$ echo ${string/%\ */}
word1
Attenzione per sfuggire al singolo spazio. Vedi qui per ulteriori esempi di modelli di sostituzione. Se hai bash> 3.0, puoi anche usare la corrispondenza delle espressioni regolari per far fronte agli spazi iniziali - vedi qui :
$ string=" word1 word2"
$ [[ ${string} =~ \ *([^\ ]*) ]]
$ echo ${BASH_REMATCH[1]}
word1
%% *Ecco un'altra soluzione che utilizza l' espansione dei parametri della shell . Si occupa di più spazi dopo la prima parola. La gestione degli spazi davanti alla prima parola richiede un'espansione aggiuntiva.
string='word1 word2'
echo ${string%% *}
word1
string='word1 word2 '
echo ${string%% *}
word1
Il %%significa l' eliminazione della corrispondenza più lunga possibile di *(uno spazio seguito da qualsiasi numero di qualsiasi altro carattere) nella parte finale di string.
Mi chiedevo come molte delle risposte migliori fossero misurate in termini di velocità. Ho testato quanto segue:
1 @ mattbh's
echo "..." | awk '{print $1;}'
2 @ ghostdog74's
string="..."; set -- $string; echo $1
3 @ boontawee-home's
echo "..." | { read -a array ; echo ${array[0]} ; }
e 4 @ boontawee-home's
echo "..." | { read first _ ; echo $first ; }
Li ho misurati con il timeit di Python in uno script Bash in un terminale Zsh su macOS, utilizzando una stringa di prova con 215 parole di 5 lettere. Ogni misurazione è stata eseguita cinque volte (i risultati erano tutti per 100 loop, meglio di 3) e hanno calcolato la media dei risultati:
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")
Bel lavoro, elettori 👏 I voti (al momento della stesura di questo documento) corrispondono alla velocità delle soluzioni!
read -anon è valido nel trattino).
echo "word1 word2" | cut -f 1 -d " "
cut taglia il 1 ° campo (-f 1) da un elenco di campi delimitati dalla stringa "" (-d "")
read È tuo amico:
Se la stringa è in una variabile:
string="word1 word2"
read -r first _ <<< "$string"
printf '%s\n' "$first"Se stai lavorando in una pipe: primo caso: vuoi solo la prima parola della prima riga:
printf '%s\n' "word1 word2" "line2" | { read -r first _; printf '%s\n' "$first"; }
secondo caso: vuoi la prima parola di ogni riga:
printf '%s\n' "word1 word2" "worda wordb" | while read -r first _; do printf '%s\n' "$first"; doneFunzionano se ci sono spazi iniziali:
printf '%s\n' " word1 word2" | { read -r first _; printf '%s\n' "$first"; }
Stavo lavorando con un dispositivo incorporato che non aveva né perl, awk o python e l'ho fatto con sed invece. Supporta più spazi prima della prima parola (che le soluzioni cute bashnon gestivano).
VARIABLE=" first_word_with_spaces_before_and_after another_word "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'
Ciò è stato molto utile quando si cercano psID di processo poiché le altre soluzioni qui che utilizzano solo bash non sono state in grado di rimuovere i primi spazi che psutilizza per allineare.