GNU wc -Lbehandelt TABs nicht als 8 Zeichen, sondern TABs so, wie sie in einem Terminal mit TAB-Stopps alle 8 Spalten angezeigt werden. Die "Breite" liegt also zwischen 1 und 8 Zeichen, je nachdem, wo sie sich in der Zeile befinden . wc -LBerücksichtigt auch die Anzeigebreite anderer Zeichen (unabhängig davon, ob sie 0, 1 oder 2 Spalten breit sind) und verarbeitet \fund \r"korrekt".
$ printf 'abcde\t\n' | wc -L
8
Hier können Sie expanddiese TABs verwenden (wobei standardmäßig auch alle 8 Spalten Tabulatoren vorausgesetzt werden, obwohl Sie sie mit Optionen ändern können), um diese TABs auf Leerzeichen zu erweitern:
git grep -h '' ./**/*.{c,h,p{l,y}} | expand | tr '\f\r' '\n\n' | grep -cE '.{81}'
(Konvertieren der CRs (die beim Senden an ein Terminal den Cursor zurück zum Zeilenanfang bewegen) und der FFs (die von einigen Anzeigegeräten als Seitenumbruch verstanden werden) in LF, um das gleiche Verhalten wie zu erhalten wc -L, die anderen jedoch zu ignorieren was wir sowieso nicht sagen können, welchen Einfluss sie auf die Anzeigebreite haben werden).
Dies gilt für TABs, jedoch nicht für Zeichen mit einfacher oder doppelter Breite. Beachten Sie, dass die GNU-Implementierung von expandderzeit TABs nicht richtig erweitert, wenn Mehrbyte-Zeichen vorhanden sind (geschweige denn Null- oder Doppelbreitenzeichen).
$ printf 'ééééé\t\n' | wc -L
8
$ printf 'ééééé\t\n' | expand | wc -L
11
Beachten Sie auch, dass ./**/*.{c,h,p{l,y}}standardmäßig versteckte Dateien oder Dateien in versteckten Verzeichnissen übersprungen werden. Wenn die Klammererweiterung auf mehrere Globs erweitert wird, werden auch Fehler (schwerwiegend mit zshoder bash -O failglob) angezeigt, wenn einer dieser Globs nicht übereinstimmt.
Mit würden zshSie verwenden, ./**/*.(c|h|p[ly])(D.)welches ein Glob ist und wo Dversteckte Dateien enthalten und .auf reguläre Dateien beschränkt sind.
Für eine Lösung, die die tatsächliche Breite der Zeichen berücksichtigt (vorausgesetzt, alle Textdateien sind in der Zeichencodierung des Gebietsschemas codiert), können Sie Folgendes verwenden:
git grep -h '' ./**/*.(c|h|p[ly])(.) | tr '\r\f' '\n\n' |
perl -Mopen=locale -MText::Tabs -MText::CharWidth=mbswidth -lne '
$n++ if mbswidth(expand($_)) > 80;
END{print 0+$n}'
Beachten Sie, dass zumindest auf GNU-Systemen mbswidth()Steuerzeichen mit einer Breite von -1und 1 für betrachtet werden expand(). Wir gehen davon aus, dass in den Dateien kein anderes Steuerzeichen als CR, NL, TAB, FF gefunden wird.
git grep -P(zumindest mit meiner 2.18.0-Version unter Debian hier) nicht mit Mehrbyte-Zeichen funktioniert. Beispielsweise wird davon ausgegangen, dass©(in Quelldateien üblich) 2 Zeichen anstelle von einem Zeichen sind, wenn es in UTF-8 codiert ist. Es ist in Ordnung mit-E. Sie können es in UTF-8-Gebietsschemasgit grep -hcP '(*UTF8)...'