Newsgroup: it.comp.os.linux.sys
Titolo: Variabili in bash

Ciao a tutti,
forse non mi sono ancora svegliato del tutto, ma non capisco perchï¿œ, quando 
alla riga 9 ottengo "1", alla 12 ottengo sempre "0"...
 1 for file in "$@"
 2 do
 3   found=0
 4   cat x.txt | while read line
 5   do
 6     if [ "$file" = "$line" ]
 7     then
 8       found=1
 9       echo "$found"
10     fi
11   done
12   echo $found
13 done
Ciao,
  Void :-?

   Void :-?
Perdona la terminologia scorretta ma, se non ricordo male, eseguendo
un
cat x.txt | while read line
finisci in un nuovo ambiente in cui "found"  non è noto; tu lo
inizializzi ad 1.
Uscendo dal while torni all'ambiente precedente in cui found era a 0.
Ciao

 Uscendo dal while torni all'ambiente precedente in cui found era a 0.
Infatti, stavo giusto scrivendo che avevo trovato quanto hai scritto tu su:
http://fvue.nl/wiki/Bash:_Piped_%60while-read'_loop_starts_subshell
Il pezzo di codice verrebbe dunque:
for file in "$@"
do
  found=$(
    cat x.txt | {
      while read line
      do
        if [ "$file" = "$line" ]
        then
          found=1
          echo $found
        fi
      done
    }
  )
done
Ciao e grazie,
  Void

 13 done
ma grep s'è rotto?
-- 
By ZeD

 ma grep s'ï¿œ rotto?
No, ma cosï¿œ mi sembra molto piï¿œ efficiente. Sbaglio?
Ciao,
  Void

 No, ma cosï¿œ mi sembra molto piï¿œ efficiente. Sbaglio?
  ï¿œ facile scoprirlo:
$ find /etc -type f > lista.txt
$ cat trova.lst
/etc/passwd
/etc/group
/etc/fstab
/etc/network/interfaces
$ type F F1
F is a function
F ()
{
    for I in "$@";
    do
        FOUND=0;
        while read L; do
            if [ "$I" = "$L" ]; then
                echo "Trovato $I";
            fi;
        done < lista.txt;
    done
}
F1 is a function
F1 ()
{
    for I in "$@";
    do
        if grep -q "$L" lista.txt; then
            echo "Trovato $I";
        fi;
    done
}
$ time F $(< trova.lst)
Trovato /etc/passwd
Trovato /etc/group
Trovato /etc/fstab
Trovato /etc/network/interfaces
real    0m0.719s
user    0m0.633s
sys     0m0.013s
$ time F1 $(< trova.lst)
Trovato  /etc/passwd
Trovato  /etc/group
Trovato  /etc/fstab
Trovato  /etc/network/interfaces
real    0m0.031s
user    0m0.007s
sys     0m0.003s
  ï¿œ molto piï¿œ veloce grep.
  Ciao,
-- 
Alessandro Selli 
http://alessandro.route-add.net
AVVERTENZA: i messaggi inviati a "trappola" non mi arriveranno.
WARNING: messages sent to "trappola" will never reach me.

  È molto più veloce grep.
E forse si puo' addirittura usare una qualche forma di "grep -x -F -f
lista.lst lista.txt" :-)
Leonardo TMTOWTDI
-- 
Surstangas via akcipitr', la cxeval' fojnumas nur:
Jen vigla damo en brakum', kaj vi pensas pri forkur'?
Do li turnis sin, kaj turnis sin, kaj ekdormis sen singard';
Kaj lin apudis je l' vekigx, soldatoj kaj Barnard'.

   È molto più veloce grep.
Ma no!
~$ cat prova.sh
#! /bin/bash
for file in "$@"
do
  found=0
  cat x.txt | while read line
  do
    if [ "$file" = "$line" ]
    then
      found=1
      echo "$found $file"
    fi
  done
  echo $found
done
~$ find . -name '*.txt' > x.txt
~$ wc -l x.txt
103 x.txt
~$ time find . | grep -f x.txt > /dev/null
0.03user 0.08system 0:00.71elapsed 17%CPU (0avgtext+0avgdata 0maxresident)k
0inputs+0outputs (0major+391minor)pagefaults 0swaps
~$ time prova.sh $(find .) > /dev/null
^C
~$
Dopo un'ora ho dato ctrl-C

   ï¿œ molto piï¿œ veloce grep.
Fantastico! Nel mio caso specifico non ï¿œ cosï¿œ eclantante, ma ï¿œ comunque 2/3 
volte piï¿œ veloce! Grazie!
Ciao,
  Void

 lista.lst lista.txt" :-)
Interessante, ma tutto quello che ho ottenuto ï¿œ una stampa del contenuto di 
una delle due liste e un "Trovato" alla fine... :-?
Ciao,
  Void

una delle due liste e un "Trovato" alla fine... :-?
find . | grep -F -x -f test.lst | sed -e 's/.*/Trovato: &/g'
oppure
find . | grep -F -x -f test.lst | tee puppa | sed -e 's/.*/Trovato: &/g' ;
wc -l < puppa | sed -e 's/.*/Totale: &/g' && rm puppa
se vuoi in fondo anche il numero dei totali.
Chiaro che se metti in "test.lst" dei file che sono TUTTI presenti, quello
che ti verra' fuori sara'... il contenuto di test.lst.
Leonardo


 find . | grep -F -x -f test.lst | sed -e 's/.*/Trovato: &/g'
Bellissimo! Quindi il seguente pezzo di script che aggiunge ad f.txt 
eventuali nuovi file presenti:
for file in /home/a/C/*
do
  if ! grep -q "$file" f.txt; then
    echo "$file" >> f.txt.tmp
  fi
done
potrebbe essere riscritto come:
find /home/a/C/ -type f | grep -v -F -x -f f.txt >> f.txt
Fico!
Per l'inverso, ovvero cancellare da f.txt i file eventualmente non piï¿œ 
presenti, mantenendo l'ordinamento di f.txt:
cat f.txt.tmp f.txt | while read line
do
  for file in /home/a/C/*
  do
    if [ "$file" = "$line" ]
    then
      echo "$file" >> f.txt.tmp2
    fi
  done
done
ho provato con questo:
find /home/a/C/ -type f > f.tmp
cat f.txt | grep -F -x -f f.tmp > f.tmp2
rm f.tmp
mv f.tmp2 f.tmp
Funziona, ma sarebbe piï¿œ elegante senza f.tmp... :-)
Ciao e grazie,
  Void

 mv f.tmp2 f.tmp
mv f.tmp2 f.txt
Ops,
  Void