Ich muss die Position eines Zeichens in einer Zeichenfolge mit dem Befehl grep identifizieren.
Beispiel ist die Zeichenfolge RAMSITALSKHMAN|1223333
.
grep -n '[^a-zA-Z0-9\$\~\%\#\^]'
Wie finde ich die Position |
in der angegebenen Zeichenfolge?
text-processing
grep
string
user82782
quelle
quelle
Antworten:
Mit können
-b
Sie den Byte-Offset ermitteln, der der Position für einfachen Text entspricht (jedoch nicht für UTF-8 oder ähnliches).Oben benutze ich den
-a
Schalter, um grep anzuweisen, die Eingabe als Text zu verwenden. erforderlich, wenn Binärdateien bearbeitet werden und der-o
Schalter nur die übereinstimmenden Zeichen ausgibt.Wenn Sie nur die Position möchten, können Sie grep verwenden, um nur die Position zu extrahieren:
Wenn Sie eine seltsame Ausgabe erhalten, prüfen Sie, ob in grep Farben aktiviert sind. Sie können Farben deaktivieren, indem Sie
--colors=never
an grep übergeben oder dem Befehl grep ein\
(das alle Aliase deaktiviert) voranstellen. Beispiel:Für eine Zeichenfolge, die mehrere Übereinstimmungen zurückgibt, leiten
head -n1
Sie die Pipe durch , um die erste Übereinstimmung zu erhalten.Beachten Sie, dass ich oben beides verwende und dass letzteres nicht funktioniert, wenn grep über eine ausführbare Datei (Skript oder auf andere Weise) "aliasiert" ist, nur wenn Aliase verwendet werden.
quelle
2
;)^
:)0:|
als output-- weil 0 die Byte-Position des Zeilenanfangs|
ist, an der gefunden wird.grep (GNU grep) 2.27
. Verwenden Sie vielleicht OS X?Versuchen:
Ausgabe:
Dies gibt Ihnen die Position mit Index-1.
quelle
printf '%s\n' '|' | grep -o . | grep -n '|'
druckt1
nicht0
wie erwartet.Wenn Sie die Bash- Shell verwenden, können Sie rein integrierte Operationen verwenden, ohne externe Prozesse wie grep oder awk starten zu müssen :
Hierbei wird eine Parametererweiterung verwendet , um alle Vorkommen von
|
Folgen durch eine beliebige Zeichenfolge zu entfernen und diese in einer temporären Variablen zu speichern. Es geht dann nur noch darum, die Länge der temporären Variablen zu messen, um den Index von zu erhalten|
.Beachten Sie, dass
if
überprüft wird, ob das|
überhaupt in der ursprünglichen Zeichenfolge vorhanden ist. Ist dies nicht der Fall, entspricht die temporäre Variable dem Original.Beachten Sie auch, dass dies den auf Null basierenden Index liefert, der
|
im Allgemeinen beim Indizieren von Bash-Strings nützlich ist. Wenn Sie jedoch einen einseitigen Index benötigen, können Sie dies tun:quelle
Sie können die awk-
index
Funktion verwenden, um die Position in Zeichen zurückzugeben, an der die Übereinstimmung auftritt:Wenn es Ihnen nichts ausmacht, die Perl-
index
Funktion zu verwenden, werden keine, ein oder mehrere Vorkommen eines Zeichens gemeldet:Nur aus Gründen der Lesbarkeit wurde die Pipeline auf zwei Zeilen aufgeteilt.
Solange das Zielzeichen gefunden wird, wird
index
ein positiver Wert basierend auf Null (0) zurückgegeben. Daher ist die Zeichenfolge "abc | xyz | 123456 | zzz |" Beim Parsen werden die Positionen 0, 4, 8, 15 und 19 zurückgegeben.quelle
RAMSITALSKHMAN|1|223333
Wir können es auch mit "expr match" oder "expr index" machen
Ausdruck stimmt mit $ string $ substring überein, wobei $ substring eine RE ist.
Und oben geben Sie die Position an, da sie die Länge der übereinstimmenden Teilzeichenfolge zurückgibt.
Genauer gesagt für den Suchindex:
quelle
awk
Lösungen trivial modifiziert werden können, um diese Informationen in jeder Zeile einer Datei zu melden (alles, was Sie tun müssen, ist dasEND
, was nie wirklich nötig war, aus JRFergusons Antwort zu entfernen , und Avinash Rajs tut es bereits) ;expr
Um dies mit der Lösung zu tun, müssten Sie eine explizite Schleife hinzufügen (und die Antwort von Gnouc ist, wie ich sehen kann, nicht leicht anpassbar, um dies überhaupt zu tun), und (2) dieawk
Lösungen können angepasst werden, um alle zu melden passt in jeder Zeile etwas leichter als dieexpr
Lösung (tatsächlich macht Avinash Rajs das auch schon).echo `...`
hier verwenden?Noch ein awk Befehl ,
Indem Sie das Feldtrennzeichen als Nullzeichenfolge festlegen, wandelt awk einzelne Zeichen im Datensatz als separate Felder um.
quelle
Einige Alternativen sind:
Ähnlich wie Gnoucs Antwort, aber mit der Shell:
mit
sed
unddc
möglicherweise über mehrere Zeilen:mit
$IFS
...Das wird dir auch sagen, wie viele es sind wie ...
quelle