Ich habe zwei Saiten. Für das Beispiel sind sie wie folgt gesetzt:
string1="test toast"
string2="test test"
Ich möchte, dass die Überlappung am Anfang der Zeichenfolgen beginnt. Mit Überlappung meine ich die Zeichenfolge "test t" in meinem obigen Beispiel.
# I look for the command
command "$string1" "$string2"
# that outputs:
"test t"
Wenn die Zeichenfolgen string1="atest toast"; string2="test test"
wären, hätten sie keine Überlappung, da die Prüfung am Anfang und das "a" am Anfang beginnt string1
.
bash
text-processing
string
verwechseln
quelle
quelle
Antworten:
Sie können sich eine Funktion wie diese vorstellen, bei der eine Fehlerprüfung hinzugefügt werden muss
quelle
[[ -z "$1$2" ]] && return
behebt es.64
0m0.005s vs 0m0.003s -128
0m0.013s vs 0m0.003s -256
0m0.041s vs 0m0.003s -512
0m0.143s vs 0m0.005s -1024
0m0.421s vs 0m0.009s -2048
0m1.575s vs 0m0.012s -4096
0m5.967s vs 0m0.022s -8192
0m24.693s vs 0m0.049s -16384
1m34.004s vs 0m0.085s -32768
6m34.721s vs 0m0.168s -65536
27m34.012s vs 0m0.370sn
th-Zeichen zu erhalten, müssen Zeichen gescannt werden,n
um zu überprüfen, ob es sich nicht um das nullbyte mit Zeichenfolge handelt. Dies steht im Einklang damit, dass bash kein Null-Byte in einer Variablen speichern kann.Dies kann vollständig innerhalb von Bash erfolgen. Obwohl die Manipulation von Zeichenfolgen in einer Schleife in Bash langsam ist, gibt es einen einfachen Algorithmus, der in Bezug auf die Anzahl der Shell-Operationen logarithmisch ist. Daher ist reine Bash auch für lange Zeichenfolgen eine praktikable Option.
Die Standard-Toolbox enthält
cmp
den Vergleich von Binärdateien. Standardmäßig gibt es den Byte-Offset der ersten unterschiedlichen Bytes an. Es gibt einen Sonderfall, wenn eine Zeichenfolge ein Präfix der anderen ist:cmp
Erzeugt eine andere Nachricht auf STDERR; Eine einfache Möglichkeit, damit umzugehen, besteht darin, die kürzeste Zeichenfolge zu verwenden.Beachten Sie, dass dies
cmp
mit Bytes funktioniert, die String-Manipulation von bash jedoch mit Zeichen. Dies macht einen Unterschied bei Multibyte-Gebietsschemas, beispielsweise bei Gebietsschemas, die den UTF-8-Zeichensatz verwenden. Die obige Funktion gibt das längste Präfix einer Byte-Zeichenfolge aus. Um Zeichenfolgen mit dieser Methode zu verarbeiten, können wir die Zeichenfolgen zunächst in eine Codierung mit fester Breite konvertieren. Angenommen, der Zeichensatz des Gebietsschemas ist eine Teilmenge von Unicode, passt UTF-32 in die Rechnung.quelle
while char-by-char
, warte ich immer noch darauf, während ich dies schreibe .. die Zeit vergeht .. wartet immer noch (vielleicht gibt es etwas falsch mit meinem System) .. die Zeit vergeht .. es muss etwas falsch sein; es sind nur 10.000 iterationen! Ah! Geduld ist eine Tugend (in diesem Fall vielleicht ein Fluch). 13m53.755s .. vs, 0m0.322scmp
sind sie die schnellsten (basieren jedoch nicht auf Zeichen). Das nächste isticonv
und dann die sehr respektabel schnellebinary-split
Antwort. Danke Gilles. Ich habe ein Jahr gebraucht, um an diesen Punkt zu gelangen, aber besser spät als nie. (PS. 2 Tippfehler Mods imiconv
Code:$
in=$LC_CTYPE}
und\
inUTF-32) \
) ... PPS. Tatsächlich war die oben erwähnte Zeichenfolge länger als 10.000 Zeichen. Es war das Ergebnis von {1..10000}, nämlich 48.894, aber das ändert nichts am DifferentialAngenommen, die Zeichenfolgen enthalten in sed keine Zeilenumbrüche:
quelle
\0
. Mittr
und\0
kann die Methode Zeilenumbrüche in der Zeichenfolge verarbeiten, ....{ printf "%s" "$string1" |tr \\n \\0; echo; printf "%s" "$string2" |tr \\n \\0; echo; } | sed -e 'N;s/^\(.*\).*\n\1.*$/\1/' |tr \\0 \\n
sed
Methode gerade etwas weiter getestet , und es scheint, dass die Verwendung von Rückverweisen auf diese Weise (im Suchmuster) sehr teuer ist. Es übertrifft immer noch die sequentielle Byte-für-Byte-Schleife (um den Faktor 3), aber hier ist ein Beispiel: Für zwei 32-KB-Zeichenfolgen (wobei das letzte Byte unterschiedlich ist) dauert es2m4.880s
im Vergleich zu Gilles ' Binärsplit Methode0m0.168s
Das scheint mir grob, aber Sie können es mit brutaler Gewalt tun:
Ich möchte, dass es einen cleveren Algorithmus gibt, aber mit einer kurzen Suche kann ich keinen finden.
quelle