grep "^$1"
Art von Arbeiten, aber wie kann ich entkommen, "$1"
damit grep keine Zeichen darin speziell interpretiert?
Oder gibt es einen besseren Weg?
Bearbeiten:
Ich möchte nicht suchen, '^$1'
sondern nach einer dynamisch eingefügten festen Zeichenfolge, die nur dann gefunden werden soll, wenn sie am Anfang einer Zeile steht. Das habe ich mit gemeint $1
.
grep '^$1'
. Oder meintest du nicht, dass du verhindern willst, dass das$1
durch die Shell erweitert wird?grep
aber du musst zuerst jedes Sonderzeichen in deiner Zeichenketteprintf %s ^;printf %s "$1" | sed 's/[][\.*^$]/\\&/g'; } | grep -f- infile
Antworten:
Ich kann mir keine Möglichkeit vorstellen, dies mit zu tun
grep
.^
selbst ist Teil eines regulären Ausdrucks, sodass für die Verwendung regulärer Ausdrücke eine Interpretation erforderlich ist. Es ist trivial mit Teilzeichenanpassung inawk
,perl
oder was auch immer:Um mit Suchzeichenfolgen umzugehen, die Folgendes enthalten
\
, können Sie denselben Trick anwenden wie in der Antwort von 123 :quelle
\/
\\\/\/\/\\\\/
sie\\///\\/
im Programm zu sehen sind. Soweit mir bekannt ist, gibt es keine Möglichkeit, Backslashes in awk ordnungsgemäß zu umgehen, es sei denn, Sie wissen, wie viele davon im Voraus verwendet werden.Wenn Sie nur überprüfen müssen, ob eine Übereinstimmung gefunden wurde, schneiden Sie alle Eingabezeilen auf die Länge des gewünschten Präfixes (
$1
) und verwenden Sie dann grep mit festem Muster:Es ist auch einfach, die Anzahl der übereinstimmenden Zeilen zu ermitteln:
Oder die Zeilennummern aller übereinstimmenden Zeilen (Zeilennummern beginnen bei 1):
Sie könnten die Zeilennummern in
head
undtail
eingeben, um den vollständigen Text der übereinstimmenden Zeilen zu erhalten, aber zu diesem Zeitpunkt ist es einfacher, nur nach einer modernen Skriptsprache wie Python oder Ruby zu greifen.(Die obigen Beispiele gehen von Posix grep und cut aus. Sie gehen davon aus, dass die zu durchsuchende Datei von der Standardeingabe stammt, können aber leicht angepasst werden, um stattdessen einen Dateinamen zu übernehmen.)
Bearbeiten: Sie sollten auch sicherstellen, dass das Muster (
$1
) keine Zeichenfolge mit der Länge Null ist. Sonstcut
scheitert das Sprichwortvalues may not include zero
. Wenn Sie Bash verwendenset -o pipefail
, können Sie auch Fehlerausgänge mit abfangencut
.quelle
Ein Weg mit Perl, der Backslashes respektiert
Dies setzt die Umgebungsvariable v für den Befehl und gibt dann aus, wenn der Index der Variablen 0 ist, dh der Anfang der Zeile.
Sie können das auch in awk machen
quelle
Hier ist eine All-Bash-Option, die ich nicht für die Textverarbeitung empfehle, aber sie funktioniert.
Das Skript berechnet die Länge
len
des eingegebenen Parameters $ 1 und verwendet dann die Parametererweiterung in jeder Zeile, um festzustellen, ob die erstenlen
Zeichen mit $ 1 übereinstimmen. In diesem Fall wird die Zeile gedruckt.quelle
Wenn Sie
$1
reines ASCII-Format haben undgrep
die-P
Option (PCRE zu aktivieren) haben, können Sie dies tun:Die Idee hier ist,
grep -P
dass reguläre Ausdrücke mit\xXX
Literalzeichen angeben können, wobeiXX
der hexadezimale ASCII-Wert dieses Zeichens ist. Das Zeichen wird buchstäblich abgeglichen, auch wenn es sich ansonsten um ein spezielles Regex-Zeichen handelt.od
wird verwendet, um den erwarteten Zeilenanfang in eine Liste von Hexadezimalwerten umzuwandeln, die dann aneinander gereiht werden und jeweils mit dem Präfix\x
printf versehen sind.^
Dieser Zeichenfolge wird dann der erforderliche reguläre Ausdruck vorangestellt.Wenn es sich bei Ihrem
$1
Code um einen Unicode handelt, wird dies erheblich schwieriger, da keine 1: 1-Entsprechung von Zeichen zu hexadezimalen Bytes vorliegt, die von ausgegeben werdenod
.quelle
Als Filter:
Führen Sie eine oder mehrere Dateien aus:
Im Abschnitt "Zitieren von Metazeichen" der Perlre-Dokumentation wird Folgendes erläutert:
quelle
Wenn Ihr grep die Option -P hat, was PCRE bedeutet , können Sie dies tun:
Wenden Sie sich an diese Frage , und lesen Sie ggf. das PCRE-Dokument .
quelle
Wenn es ein Zeichen gibt, das Sie nicht verwenden, können Sie damit den Zeilenanfang markieren. Zum Beispiel
$'\a'
(ASCII 007). Es ist hässlich, aber es wird funktionieren:Wenn Sie die übereinstimmenden Zeilen nicht benötigen, können Sie die nachfolgenden Zeilen löschen
sed
und verwendengrep -qF
. Aber es ist viel einfacher mitawk
(oderperl
) ...quelle
Wenn Sie in einer Datei ohne Schleife suchen möchten, können Sie Folgendes verwenden:
Schneiden Sie die Datei mit der Länge der Suchzeichenfolge aus
Suchen Sie nach festen Zeichenfolgen und Zeilenumbrüchen
Verwenden Sie die Zeilennummern für so etwas wie
sed -n '3p;11p' file
Wenn Sie diese Zeilen löschen möchten, verwenden Sie
quelle