
In einem Projekt mit Tausenden von Dateien wollte ich die Gesamtzahl der Codezeilen mit den Codezeilen nur in PHP vergleichen (CSS, JavaScript usw. außer Acht lassen).
Wenn ich laufe
find . -type f | xargs wc -l
Die Summe in der letzten Zeile beträgtuntereals wenn ich laufe
find -E . -regex '.+\.(php|inc)' -type f | xargs wc -l
Wenn man bedenkt, dass es sich bei der zweiten find
um eine kleinere Dateiliste handeln muss als bei der ersten (und dass es sich dabei um eine strikte Teilmenge davon handelt) find
, wie könnte wc
im zweiten Fall eine höhere Gesamtsumme gemeldet werden?
Antwort1
xargs
kann nur passieren ARG_MAXBytes an Argumenten an wc
.
Auf meinem Mac ist ARG_MAX kleiner als die vollständigen Dateinamen und relativen Pfade der gesamten Projektdateien.ErsteBefehl, xargs
gab die Ergebnisse der find
anwc
in zwei Chargen, was bedeutete wc
, dasszwei Summen, umgeben von Tausenden von Dateinamen. Aber ARG_MAX war zufällig größer als diezweite find
Ausgabe, so dass der zweite, kleinere Fund alle ineins wc
gesamt.
Die Lösung bestand darin, diese Befehle zu verwenden, sodass ich alle Gesamtsummen ohne die (langweiligen) einzelnen Dateizählzeilen sehen konnte:
find . -type f | xargs wc -l | grep total
find -E . -regex '.+\.(php|inc)' -type f | xargs wc -l | grep total
Addieren Sie dann die einzelnen „Gesamt“-Zeilen manuell.
Antwort2
Es gibt viele Möglichkeiten, dies zu tun, und xargs
es ist nicht die beste. Hier sind ein paar:
Am einfachsten ist es,
cat
jede der gefundenen Dateien durchzuzählenfind
und die Zeilen zu zählen. Achtung, das funktioniert nur, wenn Ihre Dateinamen keine Leerzeichen oder Sonderzeichen enthalten:find . -type f | while read n; do cat $n; done | wc -l find -E . -regex '.+\.(php|inc)' -type f | while read n; do cat $n; done | wc -l
Wenn Ihre Dateinamen wahrscheinlich ungewöhnliche Zeichen (Schrägstriche, Leerzeichen usw.) enthalten, verwenden Sie stattdessen Folgendes:
find . -type f | while IFS= read -r n; do cat $n; done | wc -l find -E . -regex '.+\.(php|inc)' -type f | while IFS= read -r n; do cat $n; done | wc -l
Besser ist es,
-exec
die Option „find“ zu verwenden:find . -name "*.pep" -exec cat {} \; | wc find -E . -regex '.+\.(php|inc)' -type f -exec cat {} \; | wc
Antwort3
Verwenden Sie es awk
, um die verschiedenen „Gesamtzahlen“ der wc -l
Ausgaben zu summieren!
(Hinweis: wc -l
Gibt die Anzahl der Zeilenumbruchzeichen zurück, d. h. letzte „Zeilen“ ohne letztes \n
Zeichen werden nicht gezählt – wie es auch bei awk
oder der Fall ist sed
.)
export LC_ALL=C
find . -type f -print0 | xargs -0 wc -l |
awk '/^ *[[:digit:]]+ total$/{ total+=$1 }END{print total}'
# xargs alternatives using: find ... -exec <wc|awk|sed> ... '{}' +
#man find | less -p '{} \+'
# wc
find . -type f -exec wc -l '{}' + 2>/dev/null |
awk '/^ *[[:digit:]]+ total$/{ total+=$1 }END{print total}'
# awk
find . -type f -exec awk 'END {print NR}' '{}' + 2>/dev/null |
awk '{ total+=$1 }END{print total}'
# sed
find . -type f -exec sed -n '$=' '{}' + 2>/dev/null |
awk '{ total+=$1 }END{print total}'