Je me demande s'il existe un moyen facile de vérifier si une chaîne est une ultérieurement d'une autre chaîne de bash, en fait une subséquence avec une règle supplémentaire. Je vais expliquer.
Certaines échecs de "Apple" sont "APLE", "AL", "PP" et "ALE". Les sous-successions avec une règle supplémentaire, je veux obtenir sont celles qui commencent et se terminent par la même lettre que la chaîne, alors que "ANLE" et "ALE" correspond à mon désir. P>
J'ai fait le programme suivant : p> il est exécuté comme suivi: p> Ce programme fonctionne, mais est très lent. P> Il faut toutes les lignes du fichier, modifiez-la à l'expression de Regex, puis vérifiez s'ils correspondent, puis imprimez la ligne d'origine. Sure Exemple: P> L'une des lignes a le mot Google Strort> P> $ La recherche devient Nous vérifions cette expression avec le paramètre donné et si elle correspond, nous imprimons la ligne: Google P> Ceci fonctionne Bien, cependant, lorsque les mots de fichier.txt devient trop gros, ce programme devient trop lent. Comment puis-je accélérer mon programme, éventuellement par des sous-séquences de correspondance plus rapides. P> Cette solution renvoie rapidement, Quiff, Quin, QWERTY pour la chaîne "qwertyuihgfcvbnhjk" et seulement rapide doit être retourné, il est donc presque correct, mais pas encore. P> P>
4 Réponses :
bash code> n'a pas besoin d'utiliser Expr code> (un programme externe) pour une correspondance d'expression régulière; Il fournit un accès intégré à la bibliothèque de votre système. #!/bin/bash
while read line
do
search=$(echo "$line" | tr -s 'A-Za-z' | sed 's/./\.\*&/g;s/^\.\*//' )
[[ $1 =~ $search ]] && echo "$line"
done
Comment utiliser Grep dans mon programme?
Désolé, j'ai oublié de nourrir l'argument à Grep code>.
Le problème avec grep code> il ira simplement le contenu de 1 $ code>. Nous voulons sortir les lignes de mots.txt code>, non? Nous devrions faire la sortie de Grep la regex qu'il correspond à 1 $
Bon point. Une solution encore plus rapide, cependant, serait de faire tout cela dans un seul processus awk code>. Je vais voir si je peux obtenir ce droit après plusieurs tentatives infructueuses.
Vous pouvez utiliser un motif au lieu d'une regex. Il suffit d'insérer l'astérisque après chaque lettre de chaque mot (EXCEPET la dernière lettre) et utilisez une correspondance normale de modèle.
#!/bin/bash
while read line
do
pattern=""
for ((i=${#line}-1 ; i>=0 ; --i)) ; do
pattern="${line:i:1}*"$pattern
done
pattern=${pattern%'*'}
if [[ "$1" == $pattern ]] ; then
echo "$line"
fi
done
Essayez-le comme si: testé contre: p> sorties: p> et pour Si je vous comprends correctement, une "suivante" de Testé sur REPL P> P> set - greogdgedlqfe code> Il diffuse juste Google code>. p> Apple code> est tout ce que mathes ap * l * e code>. p>
très sympa exactement ce que je veux mettre en œuvre swype ou swiftkey
En fait, cela ne devrait pas correspondre à un * p * l * e, aucun espaces mais nécessaire pour la sortie
Petite note: le modèle Grep pour 'greogdgedlqfe' est 'gr e i> o g i> d g i> e d i> l < I> Q I> F E i> '. Je crois que la règle «supplémentaire» demandée est que le modèle soit «GR E i> O i> d g i> e d i > l q i> f * e '(commencez par g, fin avec e).
@Kamilcuk presque correct, j'ai édité ma question avec plus d'exemples et répondez pourquoi le vôtre est faux
Je pense qu'un changement mineur: 'grep -x "$ (<<<" 1 $ "TR -S' A-ZA-Z '| S /./&*/ G; S / * & //; S / * // 1; S / * $ // ') "mots.txt' s'adressera au qwertyuihgfcvbnhjk code> bug.
Il y avait une faute de frappe. Le & code> était censé être $ code>, pour supprimer le dernier. Dunno pourquoi je ne l'ai pas vu? Maintenant, il retourne rapidement pour ces 4 mots dans votre édition ....
difficile à battre performances strong> p> La clé de la performance consiste à éviter les processus supplémentaires supplémentaires. La plupart des solutions Bash présentées ici (à l'exception de la solution basée sur kamilcuk considère update 1: Mise en œuvre de Perl de la solution Kamilcuk + corrective. strong> P> Je crois que possible d'utiliser l'idée de la solution à base de grep pour créer un programme PERL qui sera encore plus rapide. Il crée un seul réégycle et testez chaque mot dans le fichier de liste de mots. Je pense que cela est aussi optimal que possible avec perl. P> perl code> avec regexp. grep code>, qui n'est pas toujours correcte) nécessitera plusieurs appels sur SED, TR, etc. Perl surperformera cette solution. Même si une solution pure bash peut être mise en œuvre (à l'aide de Bash Re, des motifs), Perl est susceptible de surperformer la surperformance, lorsque la taille de la liste des mots est grande. P> programme.pl Appl Applet < mots.txt code> p>
Pouvez-vous poster un extrait de mots.txt et d'exemple de sorties. Je ne peux pas tester votre script, certains mots qui correspondent et ne correspondent pas à certaines intrants seraient utiles. Est
apppppppple code> une recherchequence deApple code>? Parce que votre script le correspondre àApple Code>.Si je comprends bien, il n'y a que 4 suivants valides de
Apple code>:AE code>ALE code>singe code>APLE < / code>. À droite?Oui, mais appppppppppe correspondrait également à mon programme, qui est destiné.
Och? Donc,
a Pple code> a également suivi de Apple? Le "suivant" ne ressemble pas à la "sous-séquence" puis, plutôt comme une expansion. Donc, une sous-séquence ne fait que quelque chose qui correspond à la regex consistait en lettres d'un mot avec . * Code> entre les lettres, fin de l'histoire?Non, AppPPE est une pomme ultérieure parce que mon programme serre d'abord des caractères répétés. Donc Appppe devient singe et qui est ultérieur de la pomme.
Pourquoi n'utilisez-vous pas Awk pour cela?
Parce que je ne sais pas awk.
Êtes-vous toujours à la recherche de solution, faites-vous de travailler pour vous?