J'ai deux cordes. Pour les besoins de l'exemple, ils sont définis comme suit:
string1="test toast"
string2="test test"
Ce que je veux, c'est trouver le chevauchement à partir du début des chaînes. Avec chevauchement, je veux dire la chaîne "test t" dans mon exemple ci-dessus.
# I look for the command
command "$string1" "$string2"
# that outputs:
"test t"
Si les chaînes étaient, string1="atest toast"; string2="test test"
elles n'auraient aucun chevauchement puisque le contrôle commence au début et le "a" au début de string1
.
bash
text-processing
string
embrouiller
la source
la source
Réponses:
Vous pouvez penser à une fonction comme celle-ci, avec une vérification des erreurs à ajouter
la source
[[ -z "$1$2" ]] && return
le corrige.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
e caractère nécessite de scanner lesn
caractères pour vérifier qu'ils ne sont pas le zéro octet de fin de chaîne. Ceci est cohérent avec bash étant incapable de stocker un octet zéro dans une variable.Cela peut être fait entièrement à l'intérieur de bash. Bien que la manipulation de chaînes dans une boucle en bash soit lente, il existe un algorithme simple qui est logarithmique dans le nombre d'opérations du shell, donc bash pur est une option viable même pour les chaînes longues.
La boîte
cmp
à outils standard comprend pour comparer les fichiers binaires. Par défaut, il indique le décalage en octets des premiers octets différents. Il existe un cas particulier lorsqu'une chaîne est un préfixe de l'autre:cmp
produit un message différent sur STDERR; un moyen simple de résoudre ce problème consiste à prendre la chaîne la plus courte.Notez que cela
cmp
fonctionne sur les octets, mais la manipulation des chaînes de bash fonctionne sur les caractères. Cela fait une différence dans les paramètres régionaux multioctets, pour des exemples de paramètres régionaux utilisant le jeu de caractères UTF-8. La fonction ci-dessus affiche le préfixe le plus long d'une chaîne d'octets. Pour gérer les chaînes de caractères avec cette méthode, nous pouvons d'abord convertir les chaînes en un codage à largeur fixe. En supposant que le jeu de caractères des paramètres régionaux est un sous-ensemble d'Unicode, UTF-32 convient parfaitement.la source
while char-by-char
, je l'attends toujours pendant que j'écris ceci ... le temps passe ... toujours en attente (peut-être qu'il y a quelque chose mal avec mon système) .. le temps passe .. il doit y avoir quelque chose de mal; ce ne sont que 10 000 itérations! Ah! la patience est une vertu (peut-être une malédiction dans ce cas) .. 13m53.755s .. vs, 0m0.322scmp
est la plus rapide (mais n'est pas basée sur les caractères). Le suivant esticonv
et puis la réponse très respectable rapidebinary-split
. Merci Gilles. Il m'a fallu un an pour en arriver là, mais mieux vaut tard que jamais. (PS. 2 mods de typo dans leiconv
code:$
in=$LC_CTYPE}
et\
inUTF-32) \
) ... PPS. en fait, la chaîne que j'ai mentionnée ci-dessus dépassait 10 000 caractères. C'était le résultat de {1..10000} qui est de 48 894, mais cela ne change pas le différentielDans sed, en supposant que les chaînes ne contiennent aucun caractère de nouvelle ligne:
la source
\0
. En utilisanttr
et\0
, la méthode peut gérer les sauts de ligne dans la chaîne, ....{ 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
méthode un peu plus loin, et il semble que l'utilisation de références arrières de cette façon (dans le modèle de recherche) soit extrêmement coûteuse. Il surpasse toujours le bouclage octet par octet séquentiel (par un facteur d'environ 3), mais voici un exemple: pour deux chaînes de 32 Ko (avec le dernier octet différent), il faut2m4.880s
, par rapport au split binaire de Gilles méthode0m0.168s
Cela me semble grossier, mais vous pouvez le faire via la force brute:
Je veux qu'un algorithme intelligent existe, mais je n'en trouve pas avec une courte recherche.
la source