Bardzo nowy w systemie UNIX, ale nie nowy w programowaniu. Korzystanie z terminala na MacBooku. Do celów zarządzania listami słów i budowania krzyżówek próbuję się przydać z poleceniem Grep i jego odmianami. Wydaje się to dość proste, ale wcześnie się rozłączam z tym, co moim zdaniem powinno być prostym przypadkiem.
Kiedy wejdę
grep "^COW" masternospaces.txt
Dostaję to, czego chcę: listę wszystkich słów zaczynających się od COW.
Ale kiedy wejdę
grep "COW$" masternospaces.txt
Spodziewam się, że otrzymam listę słów kończących się na COW (jest wiele takich słów) i nic nie jest zwracane.
Plik jest zwykłym plikiem tekstowym, w którym każdy wiersz zawiera tylko słowo (lub frazę bez spacji) we wszystkich wielkich literach.
Masz pomysł, co się tutaj dzieje?
hexdump
aby sprawdzić dokładnie, jak formatowane są zakończenia linii. Proponuję użyć mój ulubiony format:hexdump -e '"%08_ad (0x%08_ax) "8/1 "%02x "" "8/1 "%02x "' -e '" "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt
. Przy wyjściu sprawdź zakończenia linii:0a
->LF
,0d
->CR
.Odpowiedzi:
Jak wspomniał @steeldriver, problem może być spowodowany innym stylem zakończenia linii niż
grep
się spodziewano.Aby sprawdzić zakończenia linii
Możesz użyć,
hexdump
aby sprawdzić dokładnie, jak formatowane są zakończenia linii. Sugeruję użycie mojego ulubionego formatu:Przy wyjściu sprawdź zakończenia linii:
0a
->LF
,0d
->CR
. Bardzo szybki przykład dałby coś takiego:Uwaga końca linii w formacie dos:
0d 0a
.Aby zmienić zakończenia linii
Możesz zobaczyć tutaj lub tutaj różne metody zmiany zakończeń linii za pomocą różnych narzędzi, ale jednorazowo zawsze możesz użyć vi / vim:
Grep bez zmiany czegokolwiek
Jeśli chcesz
grep
dopasować bez względu na zakończenie linii, zawsze możesz określić zakończenia linii w następujący sposób:Jeśli wyświetlana jest pusta linia, możesz sprawdzić, czy rzeczywiście coś dopasowałeś, używając
-v
opcjicat
:Mój osobisty faworyt
Możesz także grep i standaryzować dane wyjściowe, używając
sed
:gdzie
^M
uzyskuje się przez wpisanieCtrl-V Ctrl-M
na klawiaturze.Mam nadzieję że to pomoże!
źródło
[[:cntrl:]]
sugerować @ user43791 i nadal nie pasuje do mnie. To nie ma sensu. Używam GNU grep 2.20 i analizuję dane wyjściowe z nDPI, który został zapisany do pliku tekstowegocat -v yourfile.ext
, co widzisz?file
.Chociaż możesz używać „standardowej” składni RegEx z grep (jak w odpowiedzi @ user43791 ), grep ma również inne identyfikatory oznaczające granice wejściowe.
Dopasowywanie początku i końca całej linii to
\`
(backstick) (zamiast^
) i\'
(apostrof) (zamiast$
).Więc dla twojego oryginalnego polecenia użyłbyś:
grep "COW\'" masternospaces.txt
Notatka: Ważne jest również, aby pamiętać, że
?
i+
będą traktowane dosłownie, chyba że ucieczka im korzystania\?
i\+
aby im swoje odpowiedniki selektora RegEx stylu.Źródło:
grep
składnia wyrażeń regularnychźródło
Innym sposobem na usunięcie
\r
przed grep:Podoba mi się to bardzo jasne, ponieważ nie pamiętam takich rzeczy
[[:cntrl:]]
na długo.źródło
„COW $”, gdy bash ustawił parametr dla grep, zostało zinterpretowane jako „COW”, gdzie traktuje „$” jak „”, ponieważ $ jest simbolem ucieczki. gdy nic nie zostało dodane przez $, jest interpretowane jako pusty ciąg przez powłokę bash, więc powinieneś użyć grep 'COW $' masternospaces.txt.
źródło
$
, zostanie pozostawione w spokoju przez bash i użyte przez grep. Przekonaj się:echo "COW$"
-$
nadal tam będzie.W BSD grep musisz uciec „$” i zawrzeć swój ciąg w podwójnych cudzysłowach:
źródło
$
będzie on specjalny dla powłoki, ponieważ rzeczy po niej nie są poprawnymi nazwami zmiennych powłoki. Użycie pojedynczych cudzysłowów wokół ciągów statycznych jest lepszym pomysłem, ale tutaj nie ma znaczenia.