2010-02-06 18 views
3

J'ai le script suivantsortie Bourne Shell ne fonctionnera pas

cat $1 | while read line 
do 
    line=`echo $line | tr "[:lower:]" "[:upper:]"` 

    if [ "`echo $line | cut -f1 -d:`" = "foo" ] && \ 
     [ "`echo $line | cut -f2 -d:`" = "bar" ]; then 
     echo 'exsist' 
     exit 1; 
    fi 
done 

tout fonctionne jusqu'à écho et puis quand le script frappe la sortie, il ne fonctionne pas et continue à aller. Des idées.

Merci

+0

UUOC: au lieu de chat 1 $ | while ... vous pouvez le faire while ... done <$ 1 –

+0

-1 pour UUOC et en utilisant des commandes externes pour chaque ligne. – ghostdog74

Répondre

5

Vous n'avez pas besoin que la barre oblique inverse - ce n'est pas le shell C.

Le problème est que la boucle while est dans une sous-shell, qui se ferme, mais comme elle est exécutée en tant que sous-shell, le script principal continue.

Dans le contexte, la solution la plus simple est probablement:

while read line 
do 
    line=`echo $line | tr "[:lower:]" "[:upper:]"` 
    if [ "`echo $line | cut -f1 -d:`" = "foo" ] && 
     [ "`echo $line | cut -f2 -d:`" = "bar" ]; then 
     echo 'exist' 
     exit 1 
    fi 
done < $1 

Si vous devez traiter plusieurs fichiers (« chat « $ @ pour » » au lieu de « cat $ 1 »), alors vous devez travailler beaucoup plus difficile plus difficile:

cat "[email protected]" | 
while read line 
do 
    line=`echo $line | tr "[:lower:]" "[:upper:]"` 
    if [ "`echo $line | cut -f1 -d:`" = "foo" ] && 
     [ "`echo $line | cut -f2 -d:`" = "bar" ]; then 
     echo 'exist' 
     exit 1 
    fi 
done 
[ $? != 0 ] && exit 1 

Cela affiche l'état de sortie du pipeline composé de « chat » et « tout », qui est l'état de sortie de la boucle « while », qui sera 1 dans la exemple si 'foo: bar' est trouvé au début d'une ligne.

Bien sûr, il existe d'autres moyens pour détecter que, par exemple:

grep -s -q "^foo:bar:" "[email protected]" && exit 1 

Cette exécute beaucoup moins de commandes que la version en boucle. (Si vous devez également utiliser '^ foo: bar $', utilisez egrep au lieu de grep simple.)

+0

Pas si difficile; en ligne de lecture; faire ...; done <<(cat "$ @") –

+0

merci beaucoup. cela a fonctionné @Charles – user174084

+1

, c'est le bashisme. – ghostdog74

0

Vous pouvez rendre vos conditionnelles insensibles à la casse en ajoutant shopt -s nocasematch au-dessus du test. Pour rétablir la casse: shopt -u nocasematch.

+0

en supposant que la balise 'bourne' signifie vraiment la bourne shell traditionnelle, Autant que ma mémoire se passe, ne pense pas qu'il existe une option nocasematch. Corrigez-moi si je me trompe. – ghostdog74

+1

En ce qui me concerne, j'ai oublié comment lire! –

1

Vous traduisez votre texte de texte minuscule en texte en majuscules, mais en effectuant des tests en minuscules, de sorte que vous n'obtenez jamais la sortie.

1

depuis que vous voulez convertir en majuscules pour chaque ligne, vous pouvez le faire comme ça

#!/bin/sh 

tr '[:lower:]' '[:upper:]' < file | while IFS=":" read -r a b c 
do 
    case "$a $b" in 
     "FOO BAR") echo "exist";exit;; 
     *) echo "$a $b";; 
    esac 
done 

OU vous pouvez le faire avec juste awk (nawk pour Solaris)

nawk -F":" ' 
topper($1)=="FOO" && topper($2)=="BAR"{ 
    print "exist" 
    exit 
} 
{ 
    print topper($0) 
} 
' file