J'ai une commande, par exemple: echo "Word1 Word2"
. Je veux mettre un tuyau (|
) et obtenir Word1 à partir de la commande.
echo "Word1 Word2" | ....
Je ne sais pas quoi mettre après le tuyau.
Awk est une bonne option si vous devez gérer les espaces de fuite, car ils s’occuperont de cela pour vous:
echo " Word1 Word2 " | awk '{print $1;}' # Prints "Word1"
Cut ne prendra pas soin de cela cependant:
echo " Word1 Word2 " | cut -f 1 -d " " # Prints nothing/whitespace
'couper' ici n'imprime rien/espace, parce que la première chose avant un espace était un autre espace.
pas besoin d'utiliser des commandes externes. Bash peut faire le travail. En supposant que "Word1 Word2" vienne de quelque part et qu'il soit stocké dans une variable, par exemple
$ string="Word1 Word2"
$ set -- $string
$ echo $1
Word1
$ echo $2
Word2
vous pouvez maintenant affecter $ 1, ou $ 2, etc. à une autre variable si vous le souhaitez.
Je pense qu'un moyen efficace est d'utiliser des tableaux 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
En outre, vous pouvez directement lire des tableaux dans un pipeline:
echo "Word1 Word2" | while read -a array; do echo "${array[0]}" ; done
echo "Word1 Word2 Word3" | { read first rest ; echo $first ; }
Cela a l'avantage de ne pas utiliser de commandes externes et de laisser les variables $ 1, $ 2, etc.
Si vous êtes sûr qu'il n'y a pas d'espaces de début, vous pouvez utiliser la substitution de paramètre bash:
$ string="Word1 Word2"
$ echo ${string/%\ */}
Word1
Attention à échapper à l'espace unique. Voir ici pour plus d’exemples de schémas de substitution. Si vous avez bash> 3.0, vous pouvez également utiliser la correspondance d’expression régulière pour faire face aux espaces principaux - voir ici :
$ string=" Word1 Word2"
$ [[ ${string} =~ \ *([^\ ]*) ]]
$ echo ${BASH_REMATCH[1]}
Word1
Vous pourriez essayer awk
echo "Word1 Word2" | awk '{ print $1 }'
Avec awk, il est très facile de choisir le mot que vous aimez (1 $, 2 $, ...)
Voici une autre solution utilisant Développement des paramètres du shell . Il prend en charge plusieurs espaces après le premier mot. La gestion des espaces devant le premier Word nécessite une extension supplémentaire.
string='Word1 Word2 '
echo ${string%% *}
Word1
Le %%
signifie la suppression de la correspondance la plus longue de *
(un espace suivi d'un nombre quelconque de caractères), en partant du côté droit de la variable string
.
echo "Word1 Word2" | cut -f 1 -d " "
cut coupe le 1er champ (-f 1) dans une liste de champs délimités par la chaîne "" (-d "")
read
est votre ami:
Si la chaîne est dans une variable:
string="Word1 Word2"
read -r first _ <<< "$string"
printf '%s\n' "$first"
Si vous travaillez dans un pipe: premier cas: vous voulez seulement le premier mot de la première ligne:
printf '%s\n' "Word1 Word2" "line2" | { read -r first _; printf '%s\n' "$first"; }
deuxième cas: vous voulez le premier mot de chaque ligne:
printf '%s\n' "Word1 Word2" "worda wordb" | while read -r first _; do printf '%s\n' "$first"; done
Ceux-ci fonctionnent s'il y a des espaces de début:
printf '%s\n' " Word1 Word2" | { read -r first _; printf '%s\n' "$first"; }
Je me demandais comment plusieurs des meilleures réponses se mesuraient en termes de rapidité. J'ai testé les éléments suivants:
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]} ; }
et 4 @ boontawee-home's
echo "..." | { read first _ ; echo $first ; }
Je les ai mesurées avec le temps de Python dans un script Bash dans un terminal Zsh sous macOS, en utilisant une chaîne de test contenant 215 mots de 5 lettres. Chaque mesure a-t-elle été effectuée cinq fois (les résultats concernaient tous 100 boucles, le meilleur des trois) et une moyenne des résultats:
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")
Beau travail, électeurs ???? Les votes (au moment d'écrire ces lignes) correspondent à la vitesse des solutions!
Je travaillais avec un périphérique intégré qui ne contenait ni Perl, awk ou python et le faisait avec sed. Il prend en charge plusieurs espaces avant le premier mot (que les solutions cut
et bash
n'ont pas gérées).
VARIABLE=" first_Word_with_spaces_before_and_after another_Word "
echo $VARIABLE | sed 's/ *\([^ ]*\).*/\1/'
Cela était très utile lorsque grepping ps
pour les ID de processus, car les autres solutions utilisant uniquement bash ne pouvaient pas supprimer les premiers espaces que ps
utilisait pour s'aligner.
Comme Perl intègre les fonctionnalités d'awk, cela peut également être résolu avec Perl:
echo " Word1 Word2" | Perl -lane 'print $F[0]'