web-dev-qa-db-fra.com

Quelles sont les différences exactes entre awk et cut with grep?

Nous savons que nous pouvons obtenir la deuxième colonne de la ligne que nous voulons à partir d'un fichier en utilisant ces deux techniques:

awk '/Word/ { print $2 }' filename

ou

grep Word filename| cut -f 2 -d ' '

Mes questions sont:

  • Quelles sont les différences entre les deux commandes ci-dessus?
  • Lequel a les meilleures performances?
  • Quels sont les avantages d'utiliser awk par rapport à cut, et vice versa?
  • Quelles options awk nous donne-t-il sur cut et vice versa?
31
Nidal

La différence la plus importante entre vos deux lignes dépend de l'entrée. cut prend un seul caractère dans -d comme délimiteur de champ (la valeur par défaut étant TAB), et chaque occurrence unique de ce caractère démarre un nouveau champ. awk, cependant, est plus flexible. Le séparateur se trouve dans la variable FS et peut être une chaîne vide (chaque caractère d'entrée crée un champ séparé), un seul caractère ou une expression régulière. Le cas spécial d'un seul caractère d'espace (par défaut) signifie de diviser sur n'importe quel séquence d'espace blanc. De plus, awk supprime par défaut les espaces de début.

Veuillez comparer:

$ echo "abc def" | cut -f 2 -d ' '
def
$ echo "abc    def" | cut -f 2 -d ' '

$ echo " abc def" | cut -f 2 -d ' '
abc


$ echo "abc def" | awk '{ print $2 }'
def
$ echo "abc    def" | awk '{ print $2 }'
def
$ echo " abc def" | awk '{ print $2 }'
def

Ici, awk se divise sur la séquence d'espaces entre abc et def tandis que cut prend chaque espace comme séparateur.

Ce que vous prenez dépendra de ce que vous voulez réaliser. Sinon, je m'attendrais à ce que cut soit plus rapide car c'est un outil plus petit et à usage unique alors que awk a son propre langage de programmation.

37
Dubu

De manière générale, plus un outil est spécialisé, plus il est rapide. Ainsi, dans la plupart des cas, vous pouvez vous attendre à ce que cut et grep soit plus rapide que sed et sed soit plus rapide que awk. Si vous comparez des pipelines plus longs d'outils plus simples avec une seule invocation d'un outil plus complexe, il n'y a pas de règle d'or. Cela ne concerne que les entrées importantes (par exemple, des millions de lignes); pour les entrées courtes, vous ne verrez aucune différence.

L'avantage des outils plus complexes est bien sûr qu'ils peuvent faire plus de choses.

Vos commandes utilisent inutilement cat. Utilisez plutôt la redirection (surtout si vous êtes préoccupé par la vitesse, même si vous ne devriez probablement pas vous inquiéter de la vitesse tant que vous n'avez pas effectué de tests de performances¹).

<fileName awk '/Word/ { print $2 }'
<fileName grep Word | cut -f 2 -d ' '

Ces commandes sont presque équivalentes. Les différences sont les suivantes:

  • awk et grep ont différentes syntaxes d'expression rationnelle . Awk et grep -E ont des syntaxes d'expression rationnelle presque identiques (expressions régulières étendues).
  • cut -d ' ' traite chaque caractère d'espace individuel comme un délimiteur. Le délimiteur par défaut d'Awk est n'importe quelle séquence d'espaces blancs, qui peut être plusieurs espaces, un onglet, etc. Vous ne pouvez pas utiliser des séquences d'espaces arbitraires comme séparateurs avec cut. Pour utiliser des espaces individuels comme séparateurs dans awk, définissez le séparateur de champ sur une expression rationnelle qui correspond à un seul espace, autre qu'une expression rationnelle composée d'un seul espace (qui est un cas spécial signifiant "toute séquence d'espaces blancs", c'est-à-dire la valeur par défaut): awk -F '[ ]' '/Word/ {print $2}'.

¹  La première règle d'optimisation de programme: ne le faites pas. La deuxième règle de l'optimisation des programmes (pour les experts seulement!): Ne le faites pas encore. - Michael A. Jackson

Votre commande,

cat fileName | awk '/Word/ { print $2 }'

Vous n'avez même pas besoin d'une commande cat. Vous pouvez essayer,

awk '/Word/ { print $2 }' filename

Et la commande ci-dessous redirige la sortie de cat vers grep puis vers cut,

cat fileName | grep Word | cut -f 2 -d ' '

Nous devons très probablement éviter la redirection de sortie. Awk fait le travail sur une seule ligne mais cut a besoin d'une commande grep pour obtenir uniquement les lignes qui contiennent un mot particulier et il imprime la colonne 2 en fonction de l'espace du délimiteur.

Vous pouvez faire les choses dans awk si cut ne parvient pas à le faire.

1
Avinash Raj