Très nouveau à UNIX mais pas nouveau à la programmation. Utilisation de la borne sur MacBook. Aux fins de la gestion et de la recherche de listes de mots pour la construction de mots croisés, j'essaie d'être utile avec la commande Grep et ses variations. Semble assez simple mais se remettez tôt avec ce que je pensais être un cas simple.
Quand j'entre
grep "^COW" masternospaces.txt
Je reçois ce que je veux: une liste de tous les mots commençant par la vache.
Mais quand j'entre
grep "COW$" masternospaces.txt
Je m'attends à obtenir une liste de mots se terminant par une vache (il y a beaucoup de tels mots), et rien n'est retourné du tout.
Le fichier est un fichier texte brut, avec chaque ligne juste un mot (ou une phrase de mots sans espaces) dans toutes les capsules.
Avez-vous une idée de ce qui pourrait arriver ici?
Comme @steeldiver mentionné, le problème est susceptible d'être causé par un style de fin de ligne différent de ce que grep
s'attend à.
Pour vérifier les terminaisons de ligne
Vous pouvez utiliser hexdump
pour vérifier exactement comment vos fins de ligne sont formatées. Je vous suggère d'utiliser mon format préféré:
hexdump -e '"%08_ad (0x%08_ax) "8/1 "%02x "" "8/1 "%02x "' -e '" "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt
Avec la sortie, vérifiez les terminaisons de ligne: 0a
-> LF
, 0d
-> CR
. Un exemple très rapide donnerait quelque chose comme ça:
$ hexdump -e '"%08_ad (0x%08_ax) "8/1 "%02x "" "8/1 "%02x "' -e '" "8/1 "%_p""|"8/1 "%_p""\n"' masternospaces.txt
00000000 (0x00000000) 4e 6f 20 43 4f 57 20 65 6e 64 69 6e 67 0d 0a 45 No COW e|nding..E
00000016 (0x00000010) 6e 64 69 6e 67 20 69 6e 20 43 4f 57 0d 0a nding in| COW..
Notez les terminaisons de ligne au format DOS: 0d 0a
.
Pour changer les terminaisons de ligne
Vous pouvez voir ici ou ICI Pour diverses méthodes de modification des terminaisons de ligne utilisant divers outils, mais pour une chose unique, vous pouvez toujours utiliser VI/Vim:
vim masternospaces.txt
:set fileformat=unix
:wq
à grep sans changer quoi que ce soit
Si vous voulez juste grep
doit correspondre, quelle que soit la ligne de fin, vous pouvez toujours spécifier des terminaisons de ligne telles que ceci:
grep 'COW[[:cntrl:]]*$' masternospaces.txt
Si une ligne vierge est affichée, vous pouvez vérifier que vous avez effectivement assorti quelque chose en utilisant le -v
Option de cat
:
grep 'COW[[:cntrl:]]*$' masternospaces.txt | cat -v
Mon préféré personnel
Vous pouvez également également grener et standardiser la sortie à l'aide de sed
:
sed -n '/COW^M*$/{;s/^M//g;p;};' masternospaces.txt
où ^M
est obtenu en tapant Ctrl-V Ctrl-M
sur votre clavier.
J'espère que cela t'aides!
Une autre façon d'enlever le \r
avant le grep:
... | dos2unix | egrep 'COW$' | ...
J'aime que c'est très clair puisque je ne me souviens pas de choses comme [[:cntrl:]]
pour longtemps.
Bien que vous puissiez utiliser la syntaxe de Regex 'standard' avec Grep (comme dans @ user43791's réponse ), Grep dispose également d'autres identificateurs de signifier les limites d'entrée.
Les correspondants pour le début et la fin de toute la ligne sont \`
(backtick) (au lieu de ^
) et \'
(Apostrophe) (au lieu de $
).
Donc, pour votre commande d'origine, vous utiliseriez: grep "COW\'" masternospaces.txt
Note latérale: Il est également important de noter que ?
et +
sera traité littéralement à moins que vous ne vous échappiez pas en utilisant \?
et \+
Pour en faire leurs homologues de sélecteur de style Regex.