Bagaimana saya bisa mengidentifikasi baris dalam file dengan panjang tertentu

12

Saya ingin menemukan baris dalam kode saya yang melebihi panjang tertentu. Kode saya ada dalam banyak file. Apa cara yang baik untuk melakukan ini?

Saya ingin tahu file dan nomor baris; konten akan lebih disukai, tetapi tidak perlu. Tujuan dari latihan ini adalah untuk kemudian mencari cara untuk mematahkan garis (mungkin secara manual).

Marcin
sumber
Bagaimana Anda menginginkan hasilnya? Seperti baris itu sendiri (kontennya, seperti dalam grep), atau sebagai nomor baris, atau sebagai sesuatu yang lain (mungkin Anda ingin menerapkan tindakan lain pada mereka)? Mungkin cara yang paling tepat untuk melakukan ini tergantung pada apa yang akan dilakukan dengan baris-baris ini selanjutnya.
imz - Ivan Zakharyaschev
@ imz - IvanZakharyaschev Poin bagus. Pertanyaan diperbarui.
Marcin

Jawaban:

13

Dengan grep:

grep -En '.{12}' file

Untuk baris, setidaknya 12 karakter.

Dengan beberapa file:

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

Beberapa grepimplementasi seperti GNU grep, dapat melakukan pencarian file sendiri.

grep -rEn '.{12}' .

Namun waspadalah terhadap symlink dan file non-reguler lainnya.

Stéphane Chazelas
sumber
Saya suka ini karena sederhana, dan saya berharap untuk melakukan sesuatu seperti ini (masih belum sempat melakukannya).
Marcin
12

Solusi AWK

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

Atau, lebih ringkas:

awk 'length > 5' file
Ramesh
sumber
9
Kami dapat mempersingkat versi Andaawk 'length > 5'
cuonglm
Gnouc adalah pembunuh penjepit;)
Ouki
1
+1 untukawk 'length > 5'
3
Dengan GNU awkyang agak kurang elegan tapi ringkasawk '/^.{6,}/'
iruvar
3
@ 1_CR, Itu POSIX dan dapat disingkat menjadi awk '/.{6}/'(sebenarnya GNU awk sampai baru-baru ini digunakan sebagai yang tidak akan berfungsi kecuali Anda melewati POSIXLY_CORRECT ke lingkungannya).
Stéphane Chazelas
5

Karena satu hal yang hilang adalah sedsolusi

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

Solusi bash

#!/bin/bash

count=0

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

Jadi, misalnya ./whatever.sh < input.file,. Ini tidak termasuk baris baru dengan mengurangi 1 dari $len; jika itu tidak diinginkan, atau input Anda menggunakan ujung CRLF, Anda harus menyesuaikannya.

goldilocks
sumber
1
mengapa tidak ${#line}menghindari exprgarpu?
iruvar
1
ha ha, +1 untuk bashsolusi murni . Tetapi harap dicatat bahwa kecuali Anda tetap IFS=di depan read, ruang utama akan diabaikan.
iruvar
1
Menambahkan beberapa praktik bagus bash. Harap perhatikan juga bahwa baris baru tidak dimasukkan $linesehingga tidak perlu mengurangi satu.
iruvar
2
@ 1_CR sebenarnya jika Anda tidak memberi readnama untuk dibaca, itu akan membacanya REPLYdan menyertakan semua spasi putih. Tidak IFSdiperlukan pengaturan.
kojiro
2
Itu akan menjadi sangat lambat dan menangani karakter backslash khusus. while readloop untuk memproses teks adalah praktik yang sangat buruk.
Stéphane Chazelas
4

Dengan perl(misalnya), dengan asumsi Anda mencari garis yang lebih panjang dari 80 karakter:

Untuk menampilkan garis:

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

Untuk menampilkan nomor baris:

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

Atau keduanya:

$ perl -nle 'print "[$.]:  $_\n" if length > 80' your_file
Ouki
sumber
3
Anda harus menambahkan -lbaris perintah, perlakan menghitung baris istirahat di baris Anda.
cuonglm
1

Ruby:

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
Rahul Patil
sumber
1

Berikut solusi bash lain (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

Array yang dihasilkan jarang, sehingga indeks array dipertahankan. Sejak kami mulai dari 1, indeks adalah nomor baris dari baris yang kami simpan. Kami dapat menampilkan hanya nomor-nomor baris itu:

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

Atau kita bisa menampilkan garis sendiri:

printf '%s\n' "${MAPFILE[@]}"
kojiro
sumber