2010-07-16 9 views
2

Je ne sais pas pourquoi la dernière ligne ne coupe pas le "du script:de script Bash pour lire un fichier

#!/bin/bash 

FILENAME=$1 
while read line 
do 
cut -d '"' -f2 
echo $line 
done < $FILENAME 

$ cat file 

"1" test 
"2" test 
"3" test 
"4" test 
"5" test 

Si je lance ce script avec la commande suivante:

$ ./test file 

2 
3 
4 
5 
"1" test 

Répondre

6

La boucle exécuterait qu'une seule fois.

  • Il lit dans la variable $line.
  • Il exécute cut -d '"' -f2 qui lit les lignes 2 à 5 du fichier (car il s'agit de l'entrée standard à ce moment-là) et imprime le numéro.
  • Il fait écho à ce qu'il a lu comme première ligne.

Fix:

cut -d '"' -f2 $FILENAME 

Si, d'autre part, vous voulez obtenir les numéros dans une variable, vous pouvez le faire dans une variété de façons, notamment:

cut -d '"' -f2 $FILENAME | 
while read number 
do # What you want 
    echo $number 
done 

ou:

while read line 
do 
    number=$(echo "$line" | cut -d '"' -f2) 
    echo $number 
done 
0

Jonathan Leffler vous a donné une méthode plus simple (qui al alors soyez plus efficace), mais dans le cas où ceci est une simplification pour quelque chose que vous allez développer (où appeler seulement couper ne fera pas ce que vous voulez), et juste pour démontrer le principe de toute façon, votre code devrait être fixé pour alimenter chaque ligne à stdin explicitement comme suit:

#!/bin/bash 

FILENAME=$1 
while read line 
do 
    echo $line | cut -d '"' -f2 
done < $FILENAME 
2

Bash peut faire tout le travail pour vous. Il n'y a pas besoin de cut:

#!/bin/bash 

FILENAME=$1 
while read -r -a line 
do 
    echo ${line//\"} 
done < "$FILENAME" 

qui lit la ligne dans un tableau, traite alors le tableau comme un scalaire qui vous donne le premier élément. Ensuite, l'expansion de l'accolade dans le echo supprime les guillemets.

Ou vous pouvez laisser cut faire tout le travail et donner Bash une longue pause café:

FILENAME=$1 
cut -d '"' -f2 "$FILENAME" 

Indiquez toujours les variables qui contiennent des noms de fichiers.

0

comme mentionné dennis, il n'y a pas besoin d'utiliser des commandes externes

$ while read -r line; do set -- $line; echo ${1//\"/}; done<file 
1 
2 
3 
4 
5 

Mais les commandes externes fonctionne plus rapidement si vous avez des fichiers très volumineux.

$ cut -d'"' -f2 file 
1 
2 
3 
4 
5 
$ awk -F'"' '{print $2}' file 
1 
2 
3 
4 
5 
$ sed 's/^"//;s/".*//' file 
1 
2 
3 
4 
5 
Questions connexes