Existe-t-il un moyen de faire en sorte que la commande cut ne lise que le dernier champ?

10

J'ai une chaîne séparée par des espaces qui est sortie par une commande, que j'aime diriger vers cut, en utilisant -fd ' 'pour diviser les espaces. Je sais que je peux utiliser -f <n>pour afficher le numéro de champ <n>, mais puis-je le faire afficher le dernier champ si je ne connais pas la longueur de la chaîne?

Ou dois-je utiliser un outil d'édition de texte plus flexible comme sedou awk?

Arronical
la source
Je pense que la commande cut ne peut pas supporter, mais je ne sais pas, avez-vous essayé avec cut -d '' -f-?
αғsнιη
3
Plus de façons de le faire: stackoverflow.com/questions/22727107/…
edwinksl
@KasiyA -nfait le n dès le début, n-est de n à la fin, et il y a l' --complementoption qui inverse la sélection. Mais pas moyen de compter le nombre de champs et d'agir en conséquence pour autant que je sache.
Arronical

Réponses:

12

Non, cutje ne peux pas faire ça. Vous pouvez utiliser deux revcommandes, comme

echo 'foo bar baz' | rev | cut -d' ' -f1 | rev

mais il est généralement plus facile à utiliser awk:

echo 'foo bar baz' | awk '{print $(NF)}'
Florian Diesch
la source
7

Vous pouvez le faire en utilisant uniquement un shell, aucun outil externe n'est nécessaire, en utilisant l'extension des paramètres:

${var##* }

var##*supprimera tout, du démarrage au dernier espace du paramètre (variable) var.

Si le délimiteur peut être n'importe quel espace, par exemple un espace ou une tabulation, utilisez la classe de caractères [:blank:]:

${var##*[[:blank:]]}

Exemple:

$ var='foo bar spam egg'

$ echo "${var##* }"
egg


$ var=$'foo\tbar\tspam\tegg'

$ echo "$var"
foo    bar    spam    egg

$ echo "${var##*[[:blank:]]}"
egg
heemayl
la source
J'avais parlé d'utiliser l'expansion des paramètres dans un commentaire sur la réponse de Severus Tux, mais la classe de caractère vierge est une information utile, merci.
Arronical
4

Personnellement, j'aime la réponse de Florian Diesch. Mais il y a aussi ce chemin.

a=$(echo "your string here" | wc -w)
echo "your string here" | cut -d' ' -f$a

Explication:

wc -wdonne le nombre de mots. et cutcoupe le dernier mot

ÉDITER:

J'ai imaginé une autre façon de le faire:

echo "Any random string here" | tac -s' ' | head -1
Severus Tux
la source
Exact, mais cela est vrai lorsque le délim est un espace ou une tabulation, et si votre délimitation coupée n'est pas la même, cela échouera
αғsнιη
Belle réflexion latérale, mais si je suis en train de régler, a="my string here"je pourrais aussi utiliser l'extension des paramètres ${a##* }.
Arronical
1
Oui, mais l'OP a dit qu'il avait une chaîne séparée par des espaces.
Severus Tux
2

En voici un qui utilise grep

$ echo "Change is Good" | grep -o '[^ ]*$'
Good

Comment ça fonctionne:

  • grep avec -oImprime uniquement les parties correspondantes (non vides) d'une ligne correspondante.
  • L'expression régulière [^ ]*$correspond à tout depuis la fin jusqu'à ce qu'elle trouve un espace.

Un autre paquebot de Glenn Jackman utilisant Perl

$ echo "Change is Good" | perl -lane 'print $F[-1]'
Good
souravc
la source