Comment identifier des lignes dans des fichiers sur une certaine longueur


12

Je voudrais trouver des lignes dans mon code qui dépassent une certaine longueur. Mon code est dans plusieurs fichiers. Quelle est la bonne façon de procéder?

J'aimerais connaître les fichiers et les numéros de ligne; le contenu serait préféré, mais pas nécessaire. Le but de l'exercice est de comprendre ensuite comment briser les lignes (probablement manuellement).


Comment voulez-vous les résultats? En tant que lignes elles-mêmes (leur contenu, comme dans grep), ou en tant que numéros de ligne, ou comme autre chose (peut-être voulez-vous leur appliquer une autre action)? La façon la plus pratique de procéder dépend probablement de ce qui sera fait avec ces lignes ensuite.
imz - Ivan Zakharyaschev

@ imz - IvanZakharyaschev Bon point. Question mise à jour.
Marcin

Réponses:


13

Avec grep:

grep -En '.{12}' file

Pour les lignes d'au moins 12 caractères.

Avec plusieurs fichiers:

find . -type f -exec grep -En '.{12}' {} +

Certaines grepimplémentations comme GNU greppeuvent faire elles-mêmes la recherche de fichiers.

grep -rEn '.{12}' .

Mais méfiez-vous des liens symboliques et autres fichiers non réguliers.


J'aime ça parce que c'est simple, et j'espérais faire quelque chose comme ça (je n'y suis toujours pas parvenu).
Marcin

12

Solution AWK

awk '{       
if (length($0) > 5)
        print $0;'} yourfile

Ou, plus concis:

awk 'length > 5' file

9
Nous pouvons raccourcir votre versionawk 'length > 5'
cuonglm

Gnouc est un tueur d'accolade;)
Ouki

1
+1 pourawk 'length > 5'

3
Avec GNU, awkle moins élégant mais concisawk '/^.{6,}/'
iruvar

3
@ 1_CR, c'est POSIX et peut être raccourci en awk '/.{6}/'(en fait, GNU awk jusqu'à récemment était celui où cela ne fonctionnerait pas à moins que vous ne passiez POSIXLY_CORRECT à son environnement).
Stéphane Chazelas

5

Puisque la seule chose qui manquait était une sedsolution

sed -n '/^.\{6,\}/p' file

5

Bash solution

#!/bin/bash

count=0

while read; do
    ((++count)) 
    len=${#REPLY}
    if ((len > 80)); then
        echo "Line $count is $len characters."
    fi
done

Ainsi, par exemple ./whatever.sh < input.file. Cela n'inclut pas la nouvelle ligne en soustrayant 1 de $len; si ce n'est pas souhaitable, ou si votre entrée utilise des terminaisons CRLF, vous devez ajuster en conséquence.


1
pourquoi ne ${#line}pas éviter la exprfourche?
iruvar

1
ha ha, +1 pour la bashsolution pure . Mais veuillez noter qu'à moins que vous ne restiez IFS=devant read, les espaces de tête seront ignorés.
iruvar

1
Ajouté dans quelques bonnes pratiques bash. Veuillez également noter que la nouvelle ligne n'est pas prise en compte, $linedonc pas besoin d'en soustraire une.
iruvar

2
@ 1_CR en fait, si vous ne donnez pas de readnom à lire, il lira REPLYet inclura tous les espaces. Aucun IFSréglage nécessaire.
kojiro

2
Cela va être extrêmement lent et gère spécialement les barres obliques inverses. while readles boucles pour traiter le texte sont de très mauvaises pratiques.
Stéphane Chazelas

4

Avec perl(par exemple), en supposant que vous recherchez des lignes de plus de 80 caractères:

Pour afficher les lignes:

$ perl -nle 'print if length > 80' your_file

Pour afficher le numéro de ligne:

$ perl -nle 'print "$.\n" if length > 80' your_file

Ou les deux:

$ perl -nle 'print "[$.]:  $_\n" if length > 80' your_file

3
Vous devez ajouter une -lligne de commande, perlcomptera le saut de ligne dans vos lignes.
cuonglm

1

Rubis:

ruby -lne 'puts $_ if $_.size > 5' intputfile

Python:

python -c "import sys;[ sys.stdout.write(''.join(line)) for line in sys.stdin if len(line.strip()) > 5 ]" < inputfile

1

Voici une autre solution bash (bash 4):

minlen=5 # minimum length of a line
mapfile -tO1 < inputfile # Map the file to the array MAPFILE (by default)
                         # Start the array at index 1
for i in "${!MAPFILE[@]}"; do
  (( ${#MAPFILE[i]} > minlen )) || unset MAPFILE[i] # Remove shorter elements
done

Le tableau résultant est rare, de sorte que les indices du tableau sont conservés. Depuis que nous avons commencé à 1, les indices sont les numéros de ligne des lignes que nous avons conservées. Nous pouvons sortir uniquement ces numéros de ligne:

printf 'Long lines found at: '
printf '%d, ' "${!MAPFILE[@]}"
echo

Ou nous pouvons sortir les lignes elles-mêmes:

printf '%s\n' "${MAPFILE[@]}"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.