Często używam grep, aby znaleźć pliki mające określony wpis, taki jak ten:
grep -R 'MyClassName'
Dobrą rzeczą jest to, że zwraca pliki, ich zawartość i oznacza znaleziony ciąg na czerwono. Złe jest to, że mam również ogromne pliki, w których cały tekst jest zapisany w jednym dużym pojedynczym wierszu. Teraz grep wyświetla zbyt wiele wyników podczas wyszukiwania tekstu w tych dużych plikach. Czy istnieje sposób, aby ograniczyć wynik do na przykład 5 słów po lewej i po prawej stronie? A może ograniczyć wydruk do 30 liter w lewo i w prawo?
command-line
text-processing
grep
Sokrates
źródło
źródło
cut
cut
, ponieważ dzieli tylko według separatora lub liczby znaków. Chociaż kiedy znajdę linięMyClassName
, może ona znajdować się w dowolnym miejscu linii i nie zawsze w tej samej pozycji. Co więcej, może występować odmiana znaków z przodu i z tyłu, co przerywa możliwość podziału według separatora.MyClassName
zostanie znaleziona linia dodatnia , chcę uzyskać nazwę pliku i znaki x po lewej i prawej stronie. x to dowolny numer, który podam, na przykład 30. Resztę zawartości pliku należy zignorować. Ma to na celu uzyskanie kontekstu dla pasujących plików i ograniczenie przeciążenia.cut
jeśli istnieją trzy pliki z następującego kodu:oiadfaosuoianavMyClassNameionaernaldfajd
i/(/&%%§%/(§(/MyClassName&((/$/$/(§/$&
ipublic class MyClassName { public static void main(String[] args) { } }
?Odpowiedzi:
grep
sam ma tylko opcje kontekstu opartego na liniach. Alternatywą jest ten post SU :Jako kolejną alternatywę zasugerowałem
fold
tekst, a następnie grep, na przykład:Ta
-s
opcja spowoduje, żefold
słowa wypychają do następnego wiersza zamiast przerywać między nimi.Lub użyj innego sposobu, aby podzielić dane wejściowe na wiersze na podstawie struktury danych wejściowych. (Na przykład post SU dotyczył JSON, więc używanie
jq
itp. Do ładnego drukowania igrep
... lub po prostujq
samodzielne filtrowanie ... byłoby lepsze niż jedna z dwóch podanych powyżej opcji).Ta metoda GNU awk może być szybsza:
-v RS=...
), i liczbę znaków w kontekście (-v n=...
)FNR > 1
) to taki, w którym awk znalazł dopasowanie do wzorca.n
końcowe znaki z poprzedniej linii (p
) in
wiodące znaki z bieżącej linii (substr($0, 0, n)
), wraz ze dopasowanym tekstem dla poprzedniej linii (która jestprt
)p
iprt
po wydrukowaniu, więc ustawiona wartość jest używana w następnym wierszuRT
jest GNUizmem, dlatego jest specyficzny dla GNU awk.W przypadku wyszukiwania rekurencyjnego może:
źródło
fold
Metoda może być stosowana tylko wtedy, gdy jesteś pewien, że szukany ciąg nie pojawia się na granicy, w przeciwnym razie byłoby uzyskać ukrytegrep
.gawk
. Niestety sugerowane polecenie zfind
losowymi danymi wyjściowymi i bez nazw plików po uruchomieniu w moim systemie. Co więcej, nie jestem wystarczająco biegły,awk
aby poprawnie przeanalizować polecenie. Obecnie Regex w połączeniu zgrep
rozwiązuje problem może nie szybko, ale niezawodnie. Jeszcze raz wielkie dzięki.RT
i prefiks itp. Miały być użyte.Używanie dopasowania tylko w połączeniu z niektórymi innymi opcjami (patrz poniżej) może być bardzo zbliżone do tego, czego szukasz, bez narzutu przetwarzania wyrażenia regularnego wymienionego w drugiej odpowiedzi
źródło
MyClassName
. Dlatego brakuje kontekstu.grep -RnHo "MyClassName"
igrep -Rno "MyClassName"
mają taką samą wydajność.-o
Flaga może być interesujące, jeśli regex miał jakieś części zmiennej. W przypadku stałego ciągu nie ma sensu go drukować za każdym razem. OP najprawdopodobniej interesuje się bliskim kontekstem.-B 1
) lub po (-A 1
). Przepraszam, że nie mogłem pomóc.