2013-02-04 19 views
0

J'ai une commande awk qui extrait la 16ème colonne de la 3ème ligne dans un fichier csv et imprime les 4 premiers caractères.Comment exécuter une commande awk dans un script shell

awk -F"," 'NR==3{print $16}' sample.csv|sed -e 's/^[ \t]*//'|awk '{print substr($0,0,4)}' 

Cela fonctionne très bien.

Mais quand je l'exécute à partir d'un script shell, je reçois et erreur

#!/bin/ksh 
YEAR=awk -F"," 'NR==3{print $16}' sample.csv|sed -e 's/^[ \t]*//'|awk '{print substr($0,0,4)}' 

Message d'erreur:

-F,: not found 
+1

Avez-vous essayé 'AN = $ (vos trucs awk | sed | awk | sed | awk ...) ' – Kent

+0

Génial !! cela a vraiment fonctionné .. merci – user2040307

+0

heureux d'aider. btw, votre combinaison 'awk | sed | awk' a fonctionné, mais c'est comme tuer une mouche par bombe nucléaire, et 3 bombes nucléaires ... il doit y avoir de la place pour s'améliorer. Eh bien, la première chose est de le faire fonctionner. :) – Kent

Répondre

1

Utilisez command substitution pour assigner la sortie d'une commande à une variable, comme le montre ci-dessous:

YEAR=$(awk -F"," 'NR==3{print $16}' sample.csv|sed -e 's/^[ \t]*//'|awk '{print substr($0,0,4)}') 
0

vous demandez au shell de faire:

VAR=value command [arguments...] 

ce qui signifie: lancer command mais le transmettre l'environnement VAR=value premier (ex: LC_ALL=C grep '[0-9]*' /some/file.txt: sera grep un certain nombre dans file.txt (et cela avec la variable LC_ALL à C juste pour la durée de l'appel de grep)

voici donc vous demander le shell de lancer la commande -F"," (c.-à--F, une fois la coquille interpréter les "," en , avec des arguments 'NR==3.......... et avec lavariablesdéfini sur la valeur awk pour la durée de l'appel de la commande.

Il suffit de le remplacer par:

#!/bin/ksh 
YEAR="$(awk -F',' 'NR==3{print $16}' sample.csv|sed -e 's/^[ \t]*//'|awk '{print substr($0,1,4)}')" 

(je n'y suis pas allé, mais j'espère qu'ils travaillent pour vous et votre fichier sample.csv)

(Notez que vous utilisez « 0 » pour correspondre à la position de caractère 1, qui fonctionne dans de nombreuses implémentations awk mais pas toutes (ie la plupart (mais pas toutes) supposent 1 quand vous écrivez 0))

+0

vous feriez mieux de placer toute la substitution dans "" comme je l'ai fait, sinon, si elle renvoie plus de 1 mot, vous finirez par invoquer un autre 'var = mot1 mot2 ....' invocation de la commande 'word2 .. ..'avec la valeur de' var' mis à 'word1' –

0

De votre description, il semble que vous vouliez extraire l'année de la 16e champ, qui peut contenir des espaces principaux. Vous pouvez l'accomplir en appelant une fois AWK:

YEAR=$(awk -F, 'NR==3{sub(/^[ \t]*/, "", $16); print ">" substr($16,1,4) "<" }') 

Mieux encore, vous n'avez même pas besoin d'utiliser awk. Puisque vous êtes déjà en train d'écrire script shell, faisons-le tout dans le script shell:

{ read line; read line; read line; } < sample.csv # Get the third line 
IFS=, set $line # Breaks line into comma-separated fields 
IFS=" " set ${16} # Trick to remove leading spaces, field 16 becomes field 1 
YEAR=${1:0:4}  # Extract the first 4 char from field 1 
+1

bon conseil sur le script awk, mais ne faites pas le shell car il est sujet à erreur (par exemple, échouera si" ligne "contient une barre oblique inverse ou d'autres caractères) et encombrant (essayez de le modifier pour qu'il fonctionne sur la ligne 67 au lieu de la ligne 3). –

+0

Je suis d'accord concernant la partie sujette aux erreurs. Modifier pour travailler avec des lignes autres que 3 n'est pas si difficile. –

+0

Rien dans le logiciel n'est "aussi dur". C'est seulement un logiciel. Le fait est que vous n'écririez pas 67 instructions de "ligne de lecture", même si vous êtes heureux d'avoir 3 instructions codées en dur dans ce script, vous devrez réécrire le script à un moment donné pour gérer un numéro de ligne différent, d'où mon affirmation que c'est lourd et mon conseil de ne pas le faire. –

0

Faites ceci:

year=$(awk -F, 'NR==3{sub(/^[ \t]+/,"",$16); print substr($16,1,4); exit }' sample.csv) 
+0

Merci à tous pour vos merveilleuses contributions. Je passe une bonne journée! – user2040307

Questions connexes