Tengo dos cuerdas Por el bien del ejemplo, se establecen así:
string1="test toast"
string2="test test"
Lo que quiero es encontrar la superposición que comienza en el comienzo de las cadenas. Con superposición me refiero a la cadena "prueba t" en mi ejemplo anterior.
# I look for the command
command "$string1" "$string2"
# that outputs:
"test t"
Si las cadenas estuvieran, string1="atest toast"; string2="test test"no tendrían superposición ya que el cheque comienza desde el principio y la "a" al comienzo de string1.
bash
text-processing
string
confundir
fuente
fuente

Respuestas:
Puede pensar en una función como esta, con alguna verificación de error para agregar
fuente
[[ -z "$1$2" ]] && returnlo arregla640m0.005s vs 0m0.003s -1280m0.013s vs 0m0.003s -2560m0.041s vs 0m0.003s -5120m0.143s vs 0m0.005s -10240m0.421s vs 0m0.009s -20480m1.575s vs 0m0.012s -40960m5.967s vs 0m0.022s -81920m24.693s vs 0m0.049s -163841m34.004s vs 0m0.085s -327686m34.721s vs 0m0.168s -6553627m34.012s vs 0m0.370sncarácter th requiere escanearncaracteres para verificar que no sean el byte cero que termina la cadena. Esto es consistente con que bash no puede almacenar un byte cero en una variable.Esto se puede hacer completamente dentro de bash. Si bien la manipulación de cadenas en un bucle en bash es lenta, existe un algoritmo simple que es logarítmico en la cantidad de operaciones de shell, por lo que bash puro es una opción viable incluso para cadenas largas.
La caja de herramientas estándar incluye
cmppara comparar archivos binarios. Por defecto, indica el desplazamiento de bytes de los primeros bytes diferentes. Hay un caso especial cuando una cadena es un prefijo de la otra:cmpproduce un mensaje diferente en STDERR; Una manera fácil de lidiar con esto es tomar la cadena que sea más corta.Tenga en cuenta que
cmpopera en bytes, pero la manipulación de cadenas de bash funciona en caracteres. Esto marca la diferencia en configuraciones regionales de varios bytes, por ejemplo, configuraciones regionales que utilizan el juego de caracteres UTF-8. La función anterior imprime el prefijo más largo de una cadena de bytes. Para manejar cadenas de caracteres con este método, primero podemos convertir las cadenas a una codificación de ancho fijo. Suponiendo que el conjunto de caracteres de la configuración regional es un subconjunto de Unicode, UTF-32 se ajusta a la factura.fuente
while char-by-char, todavía estoy esperando mientras escribo esto ... el tiempo pasa ... todavía esperando (tal vez hay algo mal con mi sistema) ... el tiempo pasa ... debe haber algo mal; ¡son solo 10,000 iteraciones! Ah! la paciencia es una virtud (quizás una maldición en este caso) .. 13m53.755s .. vs, 0m0.322scmpes la más rápida (pero no está basada en caracteres). El siguiente esiconvy luego el muy respectibly rápidabinary-splitrespuesta. Gracias Gilles Me llevó un año llegar a este punto, pero más vale tarde que nunca. (Modificaciones de error tipográfico PS 2 eniconvcódigo:$adentro=$LC_CTYPE}y\adentroUTF-32) \) ... PPS. en realidad la cadena que mencioné anteriormente tenía más de 10,000 caracteres. Fue el resultado de {1..10000} que es 48,894, pero eso no 'cambia el diferencialEn sed, suponiendo que las cadenas no contienen ningún carácter de nueva línea:
fuente
\0. Usandotry\0, el método puede manejar nuevas líneas en la cadena, ...{ printf "%s" "$string1" |tr \\n \\0; echo; printf "%s" "$string2" |tr \\n \\0; echo; } | sed -e 'N;s/^\(.*\).*\n\1.*$/\1/' |tr \\0 \\nsedmétodo un poco más, y parece que usar referencias posteriores de esta manera (en el patrón de búsqueda) es muy costoso. Todavía supera el bucle secuencial byte por byte (en un factor aproximado de 3), pero aquí hay un ejemplo: para dos cadenas de 32 kb (con el último byte diferente), toma2m4.880s, en comparación con la división binaria de Gilles método0m0.168sEsto me parece crudo, pero puedes hacerlo a través de la fuerza bruta:
Quiero que exista algún algoritmo inteligente, pero no puedo encontrar ninguno con una búsqueda corta.
fuente