bash przetwarzanie potokowe

0

Hej,
probuje uruchomic potokowo dwa polecenia grep i cp- po znalezieniu pliku, który zawiera wzorzec chcę, zeby ten plik skopiował się do bieżącego katalogu. Robię to tak:
grep "$PATTERN" "$file" -l | xargs cp -t $PWD

Problem pojawia się w przypadku plików, które są puste- dostaje wtedy taki błąd:

"cp: missing file operand
Try 'cp --help' for more information. "

Mam jeszcze drugi problem- chcę uruchomić grepa z dwoma opcjami "grep "$PATTERN" "$file" -l -n", czyli chcę żeby najpierw wydrukowała się nazwa ścieżkowa pliku, następnie numer linii w której występuje wzorzec, wraz całą linią. Ale jak uruchamiam skrypt, to zachowuje się tak jakby uwzględniał wyłacznie pierwszą opcję.

Proszę o pomoc.

2

Użyj xargs z opcją -r.

grep $pattern $file -l | xargs -r cp -t $PWD
1

-l podaje nazwę pliku raz jeśli jest przynajmniej jedno trafienie, czyli odfiltrowuje pliki których zawartość spełnia dopasowanie. Czyli grep nie przepuszcza zawartości pliku, więc nie ma powodu by podać numer linii.

0
bananananafu napisał(a):

Mam jeszcze drugi problem- chcę uruchomić grepa z dwoma opcjami "grep "$PATTERN" "$file" -l -n", czyli chcę żeby najpierw wydrukowała się nazwa ścieżkowa pliku, następnie numer linii w której występuje wzorzec, wraz całą linią.

To zadziała tylko z opcją -n pod warunkiem, że nie wskazujesz konkretnego pliku. Użyj w tym celu wieloznaczników (wildcards):

grep $pattern ${path_to_dir}/* -n

W takim wypadku grep przeszuka cały katalog, drukując na początku ścieżki do plików. Gorzej będzie jak natrafisz na podkatalog, bo grep wyrzuci komunikat:

grep: dir/subdir: Is a directory

By się przed tym ustrzec, zrobiłbym to tak:

find ${path_to_dir}/ -type f | xargs grep $pattern -n
1

@Pyxis: nie potrzebne jest to wywołanie xargs w tym przypadku. Zdecydowanie lepiej zrobić to tak:

find "${path_to_dir}" -type f -exec grep -n "$pattern" '{}' +
0
Pyxis napisał(a):

Użyj xargs z opcją -r.

grep $pattern $file -l | xargs -r cp -t $PWD

a czy da się zrobić tak, żeby przekazać nazwy ścieżkowe plików do polecenia cp, ale żeby nie drukowały się one w konsoli po wywołaniu skryptu?

UPDATE: juz działa dobrze- nie działało, bo dodałem coś do kodu zupełnie bez sensu. Dzieki za pomoc w rozwiazaniu problemu ;)

0

@Pyxis: @hauleth próbowałem to zrobić tak jak sugerujecie- z polecenim find i działało zgodnie z oczekiwaniami
ale w swoim skrypcie chcę również sprawdzać prawo czytania pliku, dlatego wymyśliłem coś takiego:

for file in $(find "$DIRECTORY" -name "*$EXTENSION")
  do
    if [ -r "$file" ]
    then
         grep "$PATTERN" "$file" -n 
    else
      echo "There is no file privilege " "$file"
    fi
done

taka jest geneza mojego problemu :D

czy da się wywołać grepa w taki sposób, zeby działał tak jak chcę w takim rozwiązaniu? Czy to rozwiazanie po prostu jest słabe?

1

Źle używasz find. Co jak twoje pliki mają w sobie spacje lub nowe linie?

Wszystko da się uzyskać przy pomocy man find oraz grepa:

find "$DIRECTORY" -name "*$EXTENSION" -a -type f -a -readable -exec grep -n "$PATTERN" '{}' +

1 użytkowników online, w tym zalogowanych: 0, gości: 1