2015-05-31 15 views
6

Mam problem z używaniem grep. Mam plik http://pastebin.com/HxAcciCa, który chcę sprawdzić dla niektórych wzorów. A kiedy "Próbuję wyszukać go grep zwraca wszystkie wiersze pod warunkiem, że wzór już istnieje w danym pliku.Dlaczego grep pasuje do wszystkich wierszy niezależnie od wzorca

Aby wyjaśnić bardziej jest to kod, który używam

grep -F "ENVIRO" "$file_pos" >> blah  

nr . znaczenia, co jeszcze mogę spróbować nawet jeśli zapewniają całą linię jako bash wzór zawsze zwraca wszystkie wiersze
są odmiany, co usiłuję:

grep -F "E20" "$file_pos" >> blah 
grep E20 "$file_pos" >> blah 
grep C:\E20-II\ENVIRO\SSNHapACS480.dll "$file_pos" >> blah 
grep -F C:\E20-II\ENVIRO\SSNHapACS480.dll "$file_pos" >> blah 

także dla jakichś dziwnych powodów podczas dodawania - x opcja grep, to nie zwraca żadnej linii, mimo że istnieje dokładny wzorzec.

Przeszukałem sieć i dokumentację bash dla przyczyny, ale nie mogłem znaleźć niczego.

Mój test końcowy był następujący

grep -F -C 1 "E20" "$store_pos" >> blah #store_pos has the same value as $file_pos 

Myślałem, że może to było drukować wiersze po wyniku, ale to nie był przypadek. Użyłem pliku blah, aby zobaczyć wyniki. Używam również Linuksowej mięty Rebecca. Ostatecznie, mimo że nazewnictwo jest dość znane, to pytanie nie jest podobne do Why does grep match all lines for the pattern "\'"

Na koniec chciałbym powiedzieć, że jestem nowy w bashu. Podejrzewam, że błąd może wynikać z głównego pliku http://pastebin.com/HxAcciCa, a nie z kodu?

+1

Dołączasz do "bla". Gdzie jest ta część, w której ją skracasz, żeby była pusta? –

+1

Rzeczy takie jak 'grep -F C: \ E20-II \ ENVIRO \ SSNHapACS480.dll" $ file_pos "' nie może działać, odwrotne ukośniki muszą być zmienione lub cytowane, jeśli chcesz je przekazać do grep. A więc: 'grep -F 'C: \ E20-II \ ENVIRO \ SSNHapACS480.dll'" $ file_pos "'. I można to połączyć z '-x'. Ale problem ten powinien mieć odwrotny skutek: nie powinieneś mieć żadnych dopasowań, a nie każdej linii jako meczu. – hvd

+1

problem z zakończeniami linii w pliku? sprawdź hexdump lub 'cat -vET filename'. –

Odpowiedz

2

Z komentarzy wynika, że ​​plik ma powody karetki ograniczające linie, a nie wyniki, które oczekuje od grep; W rezultacie, grep widzi plik jako jedną wielką linię, która albo pasuje albo nie pasuje do siebie jako całość.

(Uwaga: istnieją co najmniej trzy różne konwencje dotyczące sposobu wyznaczania linii w „zwykły tekst” plik - UNIX używa przełamane (\n), DOS/Windows wykorzystuje powrót karetki, po której następuje znak nowej linii (\r\n) oraz wersje pre-OSX z MacOS wykorzystywane tylko powrót karetki (\r))

nie jestem jasne, w jaki plik likwidacji w tym formacie, ale można je łatwo naprawić.

tr '\r' '\n' <badfile >goodfile 

lub w locie z:

tr '\r' '\n' <badfile | grep ... 
+0

Dziękuję, że to rozwiązałeś. Pewne pytanie brzmi: dlaczego kot czyta "\ r" jako^M zamiast "\ r"? – user1544624

+1

@ user1544624: Istnieje wiele różnych konwencji reprezentujących niedrukowalne znaki. '\ r' (dla" Return ") jest konwencją języka C, która jest dość szeroko stosowana. Inne, na które możesz natknąć, to '^ M' (ponieważ powrót karetki to Control-M w kodzie ASCII),' '(dla powrotu karetki),' \ 015' (kod znaku ASCII w formacie ósemkowym) i prawdopodobnie inne "Nie myślę od razu. –

2
  1. Sprawdź końca linii w pliku wejściowego: file, wc -l.
  2. Sprawdź, czy rzeczywiście używasz poprawnej grep: which grep.
  3. Użyj przekierowania wyjścia lub | more lub | less, aby nie pomylić się z wcześniejszymi próbami, do których się dodajesz.

Edytuj: Wygląda na to, że twój plik zawiera nieprawidłowe zakończenia linii (prawdopodobnie stary Mac OS (CR)). Jeśli masz dos2unix, możesz spróbować przekonwertować je na końcówki linii w stylu Unix (LF).

+0

Proszę zobaczyć moje komentarze na temat wc -l, również używam prawa grep, tj./Bin/grep – user1544624

+1

Jeśli masz dos2unix> = 7.1 możesz sprawdzić podziały linii. $ dos2unix -i HxAcciCa.htm 369 125 0 no_bom HxAcciCa.htm tekst Jak ja to widzę, plik ma 369 DOS podziały wierszy, 125 podziały wiersza UNIX i 0 Mac podziały wiersza. Jeśli przypadkowo przekonwertowałeś plik na przerwy w linii Mac, użyj polecenia mac2unix, aby przekonwertować go z powrotem na format Unix. –

1

Nie mam obecnie dostępu do komputera, ale co może być pomocne przy rozwiązywaniu problemów: 1. Użyj polecenia grep --color -F, aby sprawdzić, czy pasuje poprawnie. 2. Po wyciągu użyj | cat -A aby zobaczyć, czy istnieją jakieś zaskakujące znaki kontrolne, linie powinny kończyć się w $, inne znaki takie jak \ I lub \ M mogą czasami być bólem głowy.

Podejrzewam, że numer 2 wydaje się być wyjściem systemu Windows. W takim przypadku możesz podać nazwę pliku kota dos2unix | grep stmt powinien go rozwiązać.

Czy zapisałeś dane wyjściowe dos2unix jako inny plik? Wystarczy dokładnie sprawdzić plik powinien być podobny do tego:

[[email protected] ~]# cat -A Test.txt 
Windows^M$ 
Style^M$ 
Files^M$ 
Are^M$ 
Hard ^M$ 
To ^M$ 
Parse^M$ 


[[email protected] ~]# dos2unix Test.txt 
dos2unix: converting file Test.txt to Unix format ... 

[[email protected] ~]# cat -A Test.txt 
Windows$ 
Style$ 
Files$ 
Are$ 
Hard$ 
To$ 
Parse$ 

Teraz należy analizować właściwie - tak po prostu sprawdzić, czy nie przekonwertować plik poprawnie powodzenia!

+0

Ponieważ każda linia kończy się na^M, oznacza to, że format to mac? Próbowałem już dos2unix, ale nie zrobił tego " t zmienić cokolwiek. – user1544624

+1

^M oznacza powrót karetki, typowy dla plików systemu Windows. Więc może najpierw uruchom nazwę pliku dos2unix, aby przekonwertować ją na styl * nix, a następnie spróbuj ponownie.Możliwe, że dos2unix nie jest zainstalowany również w twoim systemie, dzięki czemu dwuetapowy proces był dobrym testem – Werner

+0

Użyłem dos2unix, ale to nie pomogło. liczba nowych wierszy wciąż wynosi 0. – user1544624

Powiązane problemy