Désolé pour cette question stupide, recherchée mais pas sûre que la bonne réponse soit trouvée, donc le séparateur par défaut n'est que de l'espace pour awk?
Voici un résumé pragmatique qui s'applique à toutes les principales implémentations Awk :
gawk
) - la valeur par défaut awk
dans certains distributions Linuxmawk
) - la valeur par défaut awk
dans certains distributions Linux (par exemple, les versions antérieures d'Ubuntu crysman signale que la version 19.04 est désormais livrée avec GNU Awk - voir son commentaire ci-dessous.)awk
sur les plates-formes de type BSD, y compris OSXSous Linux, awk -W version
Vous dira quelle implémentation est le awk
par défaut.
BSD Awk seulement comprend awk --version
(Qui GNU Awk comprend en plus à awk -W version
).
Les versions récentes de toutes ces implémentations suivent les standard POSIX par rapport aux séparateurs field[1] (mais pas record séparateurs).
Glossaire:
RS
est l'entrée -record séparateur , qui décrit comment l'entrée est divisée en enregistrements:
\n
Ci-dessous; autrement dit, l'entrée est divisée en lignes par défaut .awk
, RS
peut être spécifié comme -v RS=<sep>
.RS
à une valeur littérale, à un caractère, mais GNU Prise en charge Awk et Mawk multi-caractère valeurs cela peut être expressions régulières étendues (BSD Awk ne pas supporte cela).FS
est l'entrée -champ séparateur , qui décrit comment chaque enregistrement est divisé en champs; il peut s'agir d'une expression régulière étendue.
awk
, FS
peut être spécifié comme -F <sep>
(Ou -v FS=<sep>
).0x20
), Mais cet espace n'est pas littéralement interprété comme le (seul) séparateur, mais a signification spéciale; voir ci-dessous.Par défaut :
La spécification POSIX. tilise l'abstraction <blank>
pour les espaces et les tabulations , ce qui est vrai pour tous locales, mais pourrait comprendre supplémentaire caractères dans des paramètres régionaux spécifiques - je ne sais pas si de tels paramètres régionaux existent.
Notez que avec le séparateur d'entrée-enregistrement par défaut (RS
), \n
, sauts de ligne généralement n'entrez pas l'image comme séparateurs de champs , car aucun enregistrement lui-même contient \n
dans ce cas.
Les nouvelles lignes comme séparateurs de champs do entrent en jeu , cependant:
RS
est défini sur une valeur qui se traduit par des enregistrements eux-mêmes contenant \n
Instances (comme lorsque RS
est défini sur chaîne vide; voir ci-dessous).split()
est utilisée pour diviser une chaîne en éléments de tableau sans argument de séparation de champ explicite. \n
Dans le cas où la RS
par défaut est en vigueur, la fonction split()
lorsqu'elle est invoquée sans argument explicite de séparateur de champs sur une chaîne de plusieurs lignes provenant d'une source différente (par exemple, une variable transmise via l'option -v
ou comme pseudo-nom de fichier) toujours traite \n
comme un séparateur de champs.Considérations importantes NON par défaut :
L'affectation de la chaîne empty à RS
a une signification particulière : elle lit l'entrée dans mode paragraphe, ce qui signifie que l'entrée est divisée en enregistrements par séries de non vide lignes, avec les lignes de début et de fin des lignes vides ignorées .
Lorsque vous attribuez quelque chose autre qu'un littéral espace à FS
, le interprétation de FS
change fondamentalement :
FS
sur [ ]
- même si elle effectivement équivaut à un seul espace - provoque chaque individ instance d'espace dans chaque enregistrement à traiter comme un séparateur de champ.+
Doit être utilisé; Par exemple, [\t]+
reconnaîtrait exécute des onglets comme un seul séparateur.FS
sur chaîne vide signifie que chacun - caractère d'un enregistrement est son propre champ .RS
est défini sur chaîne vide (mode paragraphe), nouvelles lignes (\n
) sont également considérés comme des séparateurs de champs , quelle que soit la valeur de FS
.[1] Malheureusement, GNU Awk jusqu'à au moins la version 4.1.3 est conforme à une norme obsolète POSIX en ce qui concerne les séparateurs de champs lorsque vous utilisez l'option pour appliquer POSIX conformité, -P
(--posix
): avec cette option en vigueur et RS
réglé sur une valeur non vide, sauts de ligne (\n
ne sont PAS reconnus comme séparateurs de champs. Le manuel GNU Awk précise le comportement obsolète (mais néglige de mentionner qu'il ne s'applique pas lorsque RS
est défini sur la chaîne vide). La norme POSIX a changé en 2008 (voir commentaires) en aussi considérez nouvelles lignes séparateurs de champ lorsque FS
a sa valeur par défaut - comme GNU Awk a toujours fait sans-P
(--posix
).
Voici 2 commandes qui vérifient le comportement décrit ci-dessus:
* Avec -P
En vigueur et RS
réglé sur chaîne vide, \n
Est toujours traité comme un séparateur de champ:gawk -P -F' ' -v RS='' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
* Avec -P
En vigueur et un non videRS
, \n
N'EST PAS traité comme un séparateur de champ - c'est le comportement obsolète:gawk -P -F' ' -v RS='|' '{ printf "<%s>, <%s>\n", $1, $2 }' <<< $'a\nb'
n correctif arrive, selon les responsables GNU Awk; attendez-le dans la version 4.2 (aucun délai imparti) ).
(Pointe du chapeau à @JohnKugelman et @EdMorton pour leur aide.)
La question the default delimiter is only space for awk?
Est ambiguë mais je vais essayer de répondre aux deux questions que vous pourriez vous poser.
La valeur par défaut de la variable FS
(qui contient le séparateur de champ qui indique à awk comment séparer les enregistrements en champs lors de leur lecture) est un seul caractère d'espace.
La chose que awk utilise pour séparer les enregistrements en champs est un "séparateur de champs" qui est une expression régulière avec des fonctionnalités supplémentaires qui ne s'applique que lorsque le séparateur de champs est un seul caractère vide. Cette fonctionnalité supplémentaire est la suivante:
[ ]
Au lieu d'un simple caractère vide littéral comme vous le feriez dans une expression régulière.En plus des séparateurs de champs utilisés pour diviser les enregistrements en champs lors de la lecture de l'entrée, ils sont utilisés dans d'autres contextes, par ex. le troisième argument pour split()
, il est donc important pour vous de savoir quels contextes nécessitent une chaîne ou une expression rationnelle ou un fieldsep et la page de manuel spécifie clairement chacun.
Entre autres choses, ce qui précède explique ceci:
$ echo ' a b c ' | awk '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F' ' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
3: <a> <b> <c>
$ echo ' a b c ' | awk -F'[ ]' '{printf "%d: <%s> <%s> <%s>\n", NF, $1, $2, $3}'
5: <> <a> <b>
donc si vous ne comprenez pas pourquoi les 2 premiers produisent la même sortie mais que le dernier est différent, veuillez demander.
Jetons un œil à la page de manuel GNU awk:
FS
- Le séparateur de champ de saisie, un espace par défaut. Voir Champs , ci-dessus.
À la section Champs !
À mesure que chaque enregistrement d'entrée est lu, gawk divise l'enregistrement en champs, en utilisant la valeur de la variable
FS
comme séparateur de champ. SiFS
est un seul caractère, les champs sont séparés par ce caractère. SiFS
est la chaîne nulle, alors chaque caractère individuel devient un champ séparé. Sinon,FS
devrait être une expression régulière complète. Dans le cas particulier oùFS
est un seul espace, les champs sont séparés par des séries d'espaces et/ou de tabulations et/ou de nouvelles lignes.