bash przetwarzanie potokowe

BA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 47
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.

Pyxis
  • Rejestracja: dni
  • Ostatnio: dni
2

Użyj xargs z opcją -r.

Kopiuj
grep $pattern $file -l | xargs -r cp -t $PWD
MarekR22
  • Rejestracja: dni
  • Ostatnio: dni
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.

Pyxis
  • Rejestracja: dni
  • Ostatnio: dni
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):

Kopiuj
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:

Kopiuj
find ${path_to_dir}/ -type f | xargs grep $pattern -n
hauleth
  • Rejestracja: dni
  • Ostatnio: dni
1

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

Kopiuj
find "${path_to_dir}" -type f -exec grep -n "$pattern" '{}' +
BA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 47
0
Pyxis napisał(a):

Użyj xargs z opcją -r.

Kopiuj
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 ;)

BA
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 47
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:

Kopiuj
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?

hauleth
  • Rejestracja: dni
  • Ostatnio: dni
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:

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

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.