Dites que je lance la commande SayStuff
$ SayStuff
et la sortie est
Watermelons and cucumbers
À présent. Dites que je veux extraire la sous-chaîne cucumbers
de la sortie et la canaliser dans quelque chose.
La façon dont je procéderais par programme consisterait à diviser la sortie en tableau par le délimiteur Space et à le référencer par ArrayName[2]
. Je suis assez nouveau dans les scripts Shell et je n’ai réussi qu’à déterrer des exemples cut
semi-cryptiques, dont aucun n’avait de sens.
Des idées?
$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3
cucumbers
Le -d ' '
indique à cut
de se scinder en espaces. -f 3
sélectionne la troisième colonne.
Vous pouvez également utiliser awk
, qui effectue déjà la division en fonction de l'espace et rend les colonnes disponibles en tant que $1
, $2
,…
$ echo "Watermelons and cucumbers" | awk '{ print $3 }'
cucumbers
J'utiliserais probablement l'une des options déjà proposées par @slhck, mais voici quelques méthodes supplémentaires:
Utiliser des tableaux, comme dans n'importe quelle autre langue:
$ foo=( $(SayStuff) )
$ echo ${foo[2]}
cucumbers
var=()
déclare un tableau, $(command)
enregistre le résultat de la commande. Donc, foo=( $(SayStuff) )
stocke la sortie de SayStuff
dans le tableau foo
et vous alors echo
c'est son troisième élément avec ${foo[2]}
.
sed
$ SayStuff | sed 's/.* \(.*\)/\1/'
cucumbers
La commande sed
remplacera (s///
) tout par le dernier mot. La regex correspond à tout ce qui va jusqu'à un espace (.*
) qui correspond à tout jusqu'au dernier espace, puis capture le dernier Word (\(.*\)
. Puisque le mot a été capturé, on peut le nommer \1
.
Une version plus simple:
$ SayStuff | sed 's/.* //'
cucumbers
bash
$ foo=$(SayStuff); echo ${foo##* }
cucumbers
Ceci utilise les capacités de manipulation de chaîne de bash, voir ici pour plus de détails.
Plus bash
$ SayStuff | while read a b c; do echo $c; done
cucumbers
Perl, où bien sûr, il y a plusieurs façons de le faire:
$ SayStuff | Perl -lane 'print $F[$#F]'
cucumber
Le -a
fait en sorte que Perl
se comporte comme awk
, divisant les lignes par des espaces et sauvegardant dans le tableau @F
. Nous imprimons ensuite le dernier élément de @F
($#F
est le nombre d'éléments dans @F
). Le -l
demande à Perl d'ajouter une nouvelle ligne à chaque instruction print
, le -n
selon lequel il doit traiter ligne par ligne STDIN et -e
selon lequel le script doit être exécuté à la ligne de commande.
$ SayStuff | Perl -pe 's/.* //'
cucumber
Les options ont été expliquées ci-dessus, nous ne faisons que supprimer tout jusqu'au dernier espace et imprimer (-p
).
$ Perl -le 'print $ARGV[$#ARGV]' $(SayStuff)
cucumbers
Ici, nous passons Watermelons and cucumbers
en tant qu'arguments, ce que Perl enregistrera dans le tableau @ARG
. Nous imprimons donc le dernier élément de @ARG
.
tromperie. Celui-ci utilise sed
pour convertir les espaces en nouvelles lignes, puis tail
pour n’imprimer que la dernière ligne.
$ SayStuff | sed 's/ /\n/g' | tail -n 1
cucumbers
grep et expressions régulières, en utilisant -o
qui affiche uniquement la chaîne correspondante.
$ SayStuff | grep -Po '\w+$'
cucumbers
la triche
$ SayStuff | grep -o cucumbers
cucumbers
Voici quelques explications supplémentaires:
Usage: cut OPTION... [FILE]...
Print selected parts of lines from each FILE to standard output.
-d, --delimiter=DELIM
use DELIM instead of TAB for field delimiter
-f, --fields=LIST
select only these fields; also print any line that contains no
delimiter character, unless the -s option is specified
Donc si vous avez besoin du 3ème champ et qu'il soit délimité par des espaces '', alors il est
$ echo "Watermelons and cucumbers" | cut -d ' ' -f 3
cucumbers
Si vous voulez le champ LAST, vous devriez probablement utiliser awk .
Dans ce cas, il devient:
$ echo "Pastèques et concombres" | awk '{print $ NF}'
concombres
Dans awk
NF correspond au nombre de champs de la ligne, donc $NF
correspond au dernier champ de la ligne.