grep: return NULL jeśli false

1

Próbuję użyć grep do wyodrębnienia atrybutów z dużej kolekcji plików XML. Próbowałem użyć grep -E -m 1 -o -Z "<tag>(.*)</tag>" /home/somepath/*.xml || printf "NULL" ale z jakiegoś powodu nie zwraca NULL dla pliku, jeśli wyrażenie regularne się nie zgadza. Końcowa gra polega na zbudowaniu podstawowej bazy danych SQL tych plików, wykorzystując informacje ze znaczników do wypełnienia kolumn. To jest mój pierwszy atak na DB, więc może wszystko pójdzie źle?

StuporUser
źródło
1
Czy chcesz, aby NULL na plik nie pasował? The || dotyczy całego grep polecenie, więc printf zostanie wykonane tylko, jeśli grep zwraca wartość niezerową, którą zrobi tylko wtedy, gdy Nie dopasowania plików.
blm
Tak, właśnie tego chcę.
StuporUser

Odpowiedzi:

1

Jeśli chcesz coś na plik, musisz użyć grep na plik, coś w stylu:

$ find /home/somepath -type f -name '*.xml' | \
> while read path; do \
> grep -E -H -m 1 -o -Z "<tag>(.*)</tag>" "$path" || echo -e "$path\x00NULL"; \
> done

Rozbijam to:

$ find /home/somepath -type f -name '*.xml' -print | \

To generuje listę plików do przeszukania i umieszcza je w while. Jedyne, co musi zrobić, to wydrukować jedną ścieżkę na linię, więc jest wiele sposobów, aby to zrobić.

> while read path;do \

Odczytuje każdą linię do path zmienna powłoki i pętle do read zwraca false, co robi, gdy osiągnie koniec pliku, co robi, gdy find wygenerował wszystkie ścieżki, do których chce dotrzeć.

> grep -E -H -m 1 -o -Z "<tag>(.*)</tag>" "$path" || echo -e "$path\x00NULL"; \

Przeszukuje bieżący plik (w $path ). Jeśli wzorca nie ma w pliku, grep zwraca false (tzn. wychodzi z niezerowym kodem wyjścia), więc echo jest wykonywany. The -e mówi, aby interpretować ucieczki, więc echo wydrukuje bieżącą ścieżkę, ASCII nuli dosłowny NULL. To naśladować grep wyjście, które będzie bieżącą ścieżką (wymuszone przez -H, bycie grep normalnie nie wyprowadzałby ścieżki podczas przeszukiwania pojedynczego pliku), ASCII nul (z powodu -Z ) i dopasowany tekst.

> done

Zamyka while pętla.

blm
źródło
Dzięki, blm, to był odpowiedni scenariusz do pracy. Doceniam również twoje szczegółowe wyjaśnienie, najpierw pokazując mi, co robię źle, i szczegółowo wyjaśniając, dlaczego mój skrypt się nie powiódł, a następnie pokazując, jak rozwiązać problem, zamiast tylko dać mi odpowiedź.
StuporUser
@ StuporUser Cool, cieszę się, że działa dla Ciebie.
blm
0

Spróbuj tego:

grep -E -m 1 -o -Z "<tag>(.*)</tag>" /home/somepath/*.xml 2>&- || echo "NULL"
SΛLVΘ
źródło
Prawie taki sam wynik jak poprzednio; usunięto dwukropek z każdego wiersza wyjścia, ale bez innych zmian.
StuporUser
Który dwukropek? Czy możesz podać więcej kontekstu?
SΛLVΘ
„/home/somepath/B06614.xml:<author>William” stał się „/home/somepath/B06614.xml<author>William”
StuporUser
Okrężnica znika, ponieważ -Z mówi, aby zastąpić go ASCII nul.
blm