grep "^$1"
trochę działa, ale jak mam uciec, "$1"
żeby grep nie interpretował w nim żadnych znaków?
Czy jest jakiś lepszy sposób?
Edycja:
Nie chcę szukać, '^$1'
ale dynamicznie wstawianego stałego ciągu, który powinien być dopasowany tylko, jeśli znajduje się na początku linii. Właśnie to miałem na myśli $1
.
grep '^$1'
? Czy nie miałeś na myśli, że chcesz zapobiec$1
rozszerzaniu się powłoki?grep
również, ale najpierw musisz uciec od znaku specjalnego w swoim ciągu, np.printf %s ^;printf %s "$1" | sed 's/[][\.*^$]/\\&/g'; } | grep -f- infile
Odpowiedzi:
Nie mogę wymyślić sposobu, aby to zrobić za pomocą
grep
;^
samo w sobie jest częścią wyrażenia regularnego, więc użycie go wymaga interpretacji wyrażeń regularnych. To banalne korzystania dopasowywany podciąg wawk
,perl
lub cokolwiek:Aby obsłużyć ciągi zawierające
\
, możesz użyć tej samej sztuczki, co w odpowiedzi 123 :źródło
\/
\\\/\/\/\\\\/
który jest widoczny\\///\\/
w programie. O ile mi wiadomo, nie ma sposobu, aby właściwie uniknąć ukośników odwrotnych w awk, chyba że wiesz, ile z nich zostanie wykorzystanych wcześniej.Jeśli musisz tylko sprawdzić, czy znaleziono dopasowanie, wytnij wszystkie linie wejściowe do długości żądanego prefiksu (
$1
), a następnie użyj grep o stałym wzorze:Łatwo jest również uzyskać liczbę pasujących linii:
Lub numery linii wszystkich pasujących linii (numery linii zaczynają się od 1):
Możesz podać numery wierszy
head
itail
uzyskać pełny tekst pasujących wierszy, ale w tym momencie łatwiej jest sięgnąć po nowoczesny język skryptowy, taki jak Python lub Ruby.(W powyższych przykładach założono, że posix grep i cut. Zakładają, że plik do przeszukiwania pochodzi ze standardowego wejścia, ale można go łatwo dostosować do pobrania nazwy pliku.)
Edycja: Należy również upewnić się, że wzorzec (
$1
) nie jest łańcuchem zerowym. W przeciwnym raziecut
nie powievalues may not include zero
. Ponadto, jeśli używasz Bash, użyj,set -o pipefail
aby złapać wyjścia błędów przezcut
.źródło
Sposób użycia perla, który będzie szanował odwrotne ukośniki
To ustawia zmienną środowiskową v dla polecenia, a następnie drukuje, jeśli indeks zmiennej wynosi 0, tj. Początek linii.
Możesz także zrobić identycznie w awk
źródło
Oto opcja bash, nie polecam bash do przetwarzania tekstu, ale działa.
Skrypt oblicza długość
len
wprowadzonego parametru $ 1, a następnie wykorzystuje rozwinięcie parametru w każdym wierszu, aby sprawdzić, czy pierwszelen
znaki pasują do 1 $. Jeśli tak, drukuje linię.źródło
Jeśli
$1
jest czysty ASCII i twójgrep
ma-P
opcję (aby umożliwić PCRE), można to zrobić:Chodzi o to, że
grep -P
pozwala wyrażeniom regularnym\xXX
na określenie literałów, gdzieXX
jest szesnastkowa wartość ASCII tego znaku. Znak jest dopasowywany dosłownie, nawet jeśli w przeciwnym razie jest specjalnym wyrażeniem regularnym.od
służy do konwertowania oczekiwanego początku linii na listę wartości szesnastkowych, które są następnie łączone razem, z których każda poprzedzona jest\x
przez printf.^
jest następnie poprzedzany tym ciągiem, aby utworzyć wymaganą regex.Jeśli twój
$1
jest Unicode, staje się to nieco trudniejsze, ponieważ nie ma zgodności znaków 1: 1 z bajtami heksadecymalnymiod
.źródło
Jako filtr:
Uruchom jeden lub więcej plików:
Sekcja „Cytowanie metaznaków” w dokumentacji perlre wyjaśnia:
źródło
Jeśli twój grep ma opcję -P, co oznacza PCRE , możesz to zrobić:
Zapoznaj się z tym pytaniem i zapoznaj się z dokumentem PCRE, jeśli chcesz.
źródło
Jeśli istnieje znak, którego nie używasz, możesz go użyć do zaznaczenia początku linii. Na przykład
$'\a'
(ASCII 007). Jest brzydki, ale zadziała:Jeśli nie potrzebujesz dopasowanych linii, możesz porzucić końcowy
sed
i użyćgrep -qF
. Ale jest o wiele łatwiejsze dziękiawk
(lubperl
) ...źródło
Jeśli chcesz zajrzeć do pliku bez pętli, możesz użyć:
Wytnij plik o długości szukanego ciągu
Poszukaj stałych ciągów i numerów linii zwrotnych
Użyj numerów linii do czegoś takiego
sed -n '3p;11p' file
Jeśli chcesz usunąć te linie, użyj
źródło