Comment utiliser grep pour effectuer une recherche qui, lorsqu'une correspondance est trouvée, affiche le nom du fichier ainsi que les n premiers caractères de ce fichier? Notez que n
est un paramètre qui peut être spécifié et que les n premiers caractères contiennent effectivement la chaîne correspondante.Linux avec grep pour imprimer le nom du fichier et les n premiers caractères
Répondre
Vous devez rediriger la sortie de grep vers sed pour accomplir ce que vous voulez. Voici un exemple:
grep mypattern *.txt | sed 's/^\([^:]*:.......\).*/\1/'
Le nombre de points correspond au nombre de caractères que vous souhaitez imprimer. De nombreuses versions de sed fournissent souvent une option, comme -r (GNU/Linux) et -E (FreeBSD), qui vous permet d'utiliser des expressions régulières de style moderne. Cela permet de spécifier numériquement le nombre de caractères que vous souhaitez imprimer.
N=7
grep mypattern *.txt /dev/null | sed -r "s/^([^:]*:.{$N}).*/\1/"
Notez que cette solution est beaucoup plus efficace que d'autres, qui invoquent plusieurs processus.
Il y a peu d'outils qui impriment 'n caractères' plutôt que 'n lignes'. Êtes-vous sûr de vouloir vraiment des personnages et non des lignes? Le tout peut peut-être être mieux fait en Perl. Comme il est précisé (en utilisant grep
), nous pouvons faire:
pattern="$1"
shift
n="$2"
shift
grep -l "$pattern" "[email protected]" |
while read file
do
echo "$file:" $(dd if="$file" count=${n}c)
done
Les guillemets autour $file
conservent plusieurs espaces dans les noms de fichiers correctement. Nous pouvons débattre de l'utilisation de la ligne de commande, actuellement (en supposant que le nom de la commande est 'ngrep
'):
ngrep pattern n [file ...]
Je note que @litb utilisé' head -c $n
'; c'est plus propre que la commande dd
que j'ai utilisée. Il pourrait y avoir quelques systèmes sans head
(mais ils seraient assez archaïque). Je note que la version POSIX de head
prend uniquement en charge -n
et le nombre de lignes; l'option -c
est probablement une extension GNU.
grep -l pattern *.txt |
while read line; do
echo -n "$line: ";
head -c $n "$line";
echo;
done
changement -c
--n
si vous voulez voir les premières lignes n
au lieu d'octets.
Deux pensées ici:
1), vous pouvez vérifier l'état de $ [csh] après l'exécution grep sur chaque fichier Si l'efficacité n'a pas été une préoccupation (comme cela arrive jamais). Par exemple .: (Pour N caractères = 25.)
foreach FILE (file1 file2 ... fileN)
grep targetToMatch ${FILE} > /dev/null
if ($status == 0) then
echo -n "${FILE}: "
head -c25 ${FILE}
endif
end
2) GNU [FSF] tête contient un commutateur --verbose[-v]. Il offre également --null, pour accueillir les noms de fichiers avec des espaces. Et il ya '-', pour gérer les noms de fichiers comme "-c".Donc, vous pouvez faire:
grep --null -l targetToMatch -- file1 file2 ... fileN |
xargs --null head -v -c25 --
Sur ma machine linux, sed n'accepte pas de -E (grep le fait). Il fonctionne cependant avec -r –
Il cherche les N premiers caractères du fichier, pas N caractères correspondants. Ajoutez également/dev/null là-bas au cas où * .txt évalue à 0 ou 1 fichiers. Par exemple. grep mypattern * .txt/dev/null | sed ... –
Le motif RE étendu que j'ai donné ne correspondra pas aux lignes de moins de N caractères, et celles-ci seront donc correctement imprimées conformément à la spécification. Vous avez raison sur le besoin d'ajouter l'argument/dev/null. –