2 METEOROLOGICAL DATA VERSION /
8 PR TD HR ZW ZT WD WS RI # / TYPES OF MOD/TYPE/ACC
3979316.8350 1050313.7180 4857065.7030 592.1910 PR SENSOR POS XYZ/H
END OF HEADER
10 1 1 0 0 15 927.9 4.3 99.1
10 1 1 0 1 15 927.9 4.3 99.1
10 1 1 0 2 15 927.9 4.3 99.1
10 1 1 0 15 15 927.9 4.2 99.1
10 1 1 0 16 15 927.9 4.2 99.0
10 1 1 0 30 15 927.7 4.1 99.1
10 1 1 0 31 15 927.7 4.1 99.1
10 1 1 0 45 15 927.5 4.1 99.1
10 1 1 0 46 15 927.5 4.0 99.1
10 1 1 1 0 15 927.4 4.1 99.1
10 1 1 1 1 15 927.4 4.1 99.1
Dans cet exemple de données textuelles, comment puis-je extraire tous les 0,15,30,45 de la cinquième colonne de données numériques dans l’ordre, après la partie "END OF HEADER
" comme suit;
10 1 1 0 0 15 927.9 4.3 99.1
10 1 1 0 15 15 927.9 4.2 99.1
10 1 1 0 30 15 927.7 4.1 99.1
10 1 1 0 45 15 927.5 4.1 99.1
10 1 1 1 0 15 927.4 4.1 99.1
Vous pouvez le faire en utilisant sed
et awk
:
(en supposant que le texte de votre sujet se trouve dans un fichier nommé example.txt
)
sed -n '/END OF HEADER/,${
/END OF HEADER/d
p
}' example.txt | awk '($5 == 0 || $5 == 15 || $5 == 30 || $5 == 45)'
Attribution - la commande awk a été prise à partir du commentaire de steeldriver
Sed
/END OF HEADER/
/END OF HEADER/d
signifie supprimer la ligne contenant /END OF HEADER/
en dehors de l'espace de modèle, et comme elle n'est plus dans l'espace de modèle, la commande suivante p
ne fera rien.Awk
Un rapide une ligne serait:
$ awk '$5 == '0' || $5 == '15' || $5 == '30' || $5 == '45' {print}' test.txt
Comme Fedorqui mentionné dans le commentaire ci-dessous et encore plus rapide, un liner est:
$ awk '$5 ~ /^(0|15|30|45)$/' test.txt
Syntaxe expliquée:
$5 - the desired column from the text.
~ - the match symbol... matching was between the two slashes (/).
^/$ - the regex symbols indicating the beginning and end of the field.
| - the or specifier for either item in the "()" group.
L'en-tête est filtré en acceptant uniquement les lignes correspondant aux éléments suivant les critères de correspondance ~
.
Il est parfaitement faisable dans grep
, bien que awk
soit l'outil à utiliser pour les données séparées par champs.
Avec grep
:
grep -E '^10[[:blank:]]+([^[:blank:]]+[[:blank:]]+){3}(0|15|30|45)[[:blank:]]' file.txt
10
au début, ([^[:blank:]]+[[:blank:]]+){3}
correspond aux 3 champs suivants, puis au 5ème champ correspondant aux champs souhaités.Si vous utilisez PCRE (-P
), vous pouvez remplacer [:blank:]
par \s
, cela convient bien aux yeux:
grep -P '^10\s+([^\s]+\s+){3}(0|15|30|45)\s' file.txt
Exemple:
$ cat file.txt
2 METEOROLOGICAL DATA VERSION /
8 PR TD HR ZW ZT WD WS RI # / TYPES OF MOD/TYPE/ACC
3979316.8350 1050313.7180 4857065.7030 592.1910 PR SENSOR POS XYZ/H
END OF HEADER
10 1 1 0 0 15 927.9 4.3 99.1
10 1 1 0 1 15 927.9 4.3 99.1
10 1 1 0 2 15 927.9 4.3 99.1
10 1 1 0 15 15 927.9 4.2 99.1
10 1 1 0 16 15 927.9 4.2 99.0
10 1 1 0 30 15 927.7 4.1 99.1
10 1 1 0 31 15 927.7 4.1 99.1
10 1 1 0 45 15 927.5 4.1 99.1
10 1 1 0 46 15 927.5 4.0 99.1
10 1 1 1 0 15 927.4 4.1 99.1
10 1 1 1 1 15 927.4 4.1 99.1
$ grep -E '^10[[:blank:]]+([^[:blank:]]+[[:blank:]]+){3}(0|15|30|45)[[:blank:]]' file.txt
10 1 1 0 0 15 927.9 4.3 99.1
10 1 1 0 15 15 927.9 4.2 99.1
10 1 1 0 30 15 927.7 4.1 99.1
10 1 1 0 45 15 927.5 4.1 99.1
10 1 1 1 0 15 927.4 4.1 99.1
$ grep -P '^10\s+([^\s]+\s+){3}(0|15|30|45)\s' file.txt
10 1 1 0 0 15 927.9 4.3 99.1
10 1 1 0 15 15 927.9 4.2 99.1
10 1 1 0 30 15 927.7 4.1 99.1
10 1 1 0 45 15 927.5 4.1 99.1
10 1 1 1 0 15 927.4 4.1 99.1