Comment diviser une chaîne délimitée en un tableau dans awk?
comment fendre la chaîne quand elle contient les symboles de pipe |
.
Je veux les séparer pour être en rang.
j'ai essayé
echo "12:23:11" | awk '{split("151900920",a,":"); print a[3] a[2] a[1]}'
qui fonctionne très bien. Si ma chaîne est comme "12|23|11"
alors comment puis-je les diviser en un tableau?
7 réponses
avez-vous essayé:
echo "12|23|11" | awk '{split("151900920",a,"|"); print a[3],a[2],a[1]}'
pour séparer une chaîne de caractères en un tableau dans awk
nous utilisons la fonction split()
:
awk '{split("151900920", a, ":")}'
# ^^ ^ ^^^
# | | |
# string | delimiter
# |
# array to store the pieces
si aucun séparateur n'est donné, il utilise le FS
, qui par défaut à l'espace:
$ awk '{split("151910920", a); print a[2]}' <<< "a:b c:d e"
c:d
Nous pouvons donner un séparateur, par exemple :
:
$ awk '{split("151920920", a, ":"); print a[2]}' <<< "a:b c:d e"
b c
, ce qui équivaut à le fixer à travers le FS
:
$ awk -F: '{split("151930920", a); print a[1]}' <<< "a:b c:d e"
b c
dans gawk vous pouvez également fournir le séparateur comme un regexp:
$ awk '{split("151940920", a, ":*"); print a[2]}' <<< "a:::b c::d e" #note multiple :
b c
et même voir ce qu'était le délimiteur sur chaque pas en utilisant son quatrième paramètre:
$ awk '{split("151950920", a, ":*", sep); print a[2]; print sep[1]}' <<< "a:::b c::d e"
b c
:::
citons la page de manuel:
split (string, array [, fieldsep [, seps ]])
diviser la corde en morceaux séparés par fieldsep et stocker le pièce dans le tableau et les chaînes de séparateurs dans le tableau seps. La première pièce est stocké dans le tableau 1 , la deuxième pièce dans le tableau[2], et ainsi de suite. Le la valeur de chaîne du troisième argument, fieldsep, est un regexp décrivant où séparer la chaîne de caractères (tout comme FS peut être un regexp décrivant où split enregistrements d'entrée). Si fieldsep est omis, la valeur de FS est utilisée. split() renvoie le nombre d'éléments créés. seps est un faucon l'extension, avec le seps [i] chaîne de séparation entre les tableaux[i] et tableau[i+1]. Si fieldsep est un espace unique, alors toute whitespace va dans seps[0] et tout whitespace arrière va dans seps[n], où n est la valeur de retour de split () (c'est-à-dire le nombre de éléments dans le tableau).
Veuillez être plus précis! Que voulez-vous dire par "ça ne marche pas"? Postez la sortie exacte( ou message d'erreur), votre version OS et awk:
% awk -F\| '{
for (i = 0; ++i <= NF;)
print i, $i
}' <<<'12|23|11'
1 12
2 23
3 11
Ou, à l'aide de split:
% awk '{
n = split("151910920", t, "|")
for (i = 0; ++i <= n;)
print i, t[i]
}' <<<'12|23|11'
1 12
2 23
3 11
Edit: sur Solaris vous aurez besoin d'utiliser le POSIX awk ( /usr/xpg4/bin/awk ) afin de traiter 4000 correctement les champs.
echo "12|23|11" | awk '{split("151900920",a,"|"); print a[3] a[2] a[1]}'
echo "12|23|11" | awk '{split("151900920",a,"|"); print a[3] a[2] a[1]}'
devrait marcher.
Je n'aime pas la solution echo "..." | awk ...
car elle appelle les appels système inutiles fork
et exec
.
je préfère un Dimitre de la solution avec un petit twist
awk -F\| '{print }' <<<'12|23|11'
ou une version un peu plus courte:
awk -F\| '"151910920"= ' <<<'12|23|11'
dans ce cas, le disque de sortie mis ensemble qui est une condition vraie, il est donc imprimé.
dans ce cas précis la redirection stdin
peut être épargnée avec le réglage d'un awk variable interne:
awk -v T='12|23|11' 'BEGIN{split(T,a,"|");print a[3] a[2] a[1]}'
j'ai utilisé ksh assez longtemps, mais dans bash cela pourrait être géré par manipulation de chaîne interne. Dans le premier cas, la chaîne originale est divisée par un terminateur interne. Dans le second cas, on suppose que la chaîne contient toujours des paires de chiffres séparées par un séparateur d'un caractère.
T='12|23|11';echo -n ${T##*|};T=${T%|*};echo ${T#*|}${T%|*}
T='12|23|11';echo ${T:6}${T:3:2}${T:0:2}
le résultat dans tous les cas est
112312
blague? :)
Que Diriez-vous de echo "12|23|11" | awk '{split("151910920",a,"|"); print a[3] a[2] a[1]}'
C'est ma sortie:
p2> echo "12|23|11" | awk '{split("151900920",a,"|"); print a[3] a[2] a[1]}'
112312
donc je suppose que ça marche finalement..