`wc -l`로 한 줄의 줄을 어떻게 얻습니까?


12

내 역사에서 특정 파일의 행 수를 제공하기 위해 자식 별칭을 추가했습니다.

[alias]
lines = !lc() { git ls-files -z ${1} | xargs -0 wc -l; }; lc

그러나 wc -l여러 총계를보고하므로 ~ 100k 줄 이상인 경우 총계를보고 한 다음 계속 진행합니다. 예를 들면 다음과 같습니다.

<100k 라인 (원하는 출력)

$ git lines \*.xslt
  46 packages/NUnit-2.5.10.11092/doc/files/Summary.xslt
 232 packages/NUnit-2.5.10.11092/samples/csharp/_UpgradeReport_Files/UpgradeReport.xslt
 278 total

> 100k 라인 (에 파이프해야 함 grep "total")

$ git lines \*.cs | grep "total"
 123569 total
 107700 total
 134796 total
 111411 total
  44600 total

wc -l일련의 소계가 아닌 에서 총합을 얻으려면 어떻게해야 합니까?


에 따르면 stackoverflow.com/questions/2501402/... 문제 것은 함께 xargs하지 wc. 여전히 문제를 해결하는 방법에 관심이 있으며 답변에 좋은 해결책이 없습니다.
Ehryk

3
사용중인 버전이 옵션 을 wc지원 --files0-from합니까? 그럼 당신은 할 수 있습니다{ git ls-files -z ${1} | wc -l --files0-from=- ; }
Mark Plotnick

@ MarkPlotnick 그 답을 얻을 가치가 있다고 생각합니다.
terdon

아니. wc: unrecognized option '--files0-from=-'
Ehryk

답변:


12

이것을 시도하고 명확하게 사과하십시오.

cat *.cs | wc -l

또는 git으로 :

git ls-files -z ${1} | xargs -0 cat | wc -l

실제로 출력이 wc개별 카운트와 합계를 갖는 출력 과 같이 보이게 awk하려면 개별 라인을 더하는 데 사용할 수 있습니다.

git ls-files -z ${1} | xargs -0 wc -l |
awk '/^[[:space:]]*[[:digit:]]+[[:space:]]+total$/{next}
     {total+=$1;print}
     END {print total,"total"}'

그것은 wc당신에게 중요한 경우 처럼 멋지게 정렬되지 않습니다 . 이렇게하려면 전체 입력을 읽고 저장하여 총계를 계산 한 다음 필드 너비를 사용하여 기억 된 행의 형식화 된 출력을 인쇄하기 전에 총계를 사용하여 필드 너비를 계산해야합니다. 주택 개조 프로젝트와 마찬가지로 awk스크립트는 절대 완성되지 않습니다.

(열정적 인 편집자 참고 사항 : 첫 번째 awk조건 의 정규식 은 이름이 "total"로 시작하는 파일과 공백이있는 경우를위한 것입니다. 그렇지 않으면 조건이 훨씬 단순했을 수 있습니다 $2 == "total".


작동하지만 총합 ( git ls-files -z ${1} | xargs -0 cat | wc -l) 만 출력합니다 . 그러나 위의 첫 번째 예제에서와 같이 wc -l이 제공하는 파일 당 줄 수가 누락되었습니다. 두 세계를 최대한 활용하는 방법은 무엇입니까?
Ehryk

또는 너무 어려울 경우 스위치가 고장날 경우 스위치를 사용하면 어떻습니까? 그렇지 않으면 총 파일에 총 출력을 제공하여 파일 당 정상적인 화장실을 제공합니까?
Ehryk 2018 년

@ Ehryk : grep -v총 라인을 삭제하기 위해 한 번 한 번, 총 합계를 얻는 것이 제안되면 한 번만 두 번 할 수 있습니다. 또는 편집 된 답변에서 awk 솔루션을 시도해 볼 수 있습니다.
rici

+1 : "가정 리모델링 프로젝트와 마찬가지로 awk 스크립트는 실제로 완성 된 적이 없습니다."
Ehryk

그것은 매력처럼 작동했습니다. 나의 최종 결과 :git ls-files -z ${1} | xargs -0 wc -l | awk '/^[[:space:]]*[[:digit:]]+[[:space:]]+total$/{next} {total+=$1;print} END {print "\n Total:",total,"lines"}'
Ehryk

7

Linux를 실행하는 경우 wcGNU Coreutils에서 제공되는 것으로 , --files0-from계산할 NUL 종료 파일 이름 목록을 포함하는 파일 (또는 stdin)을 읽을 수있는 옵션이 있습니다. GNU로 coreutils 화장실 문서는 파일 이름의 목록이 너무 오래가 명령 줄 길이 제한을 초과 할 수 있다는 것이다 때 유용합니다 "말한다. 이러한 경우, 그것은 조각으로 목록을 분할하고 화장실 인쇄를 만들기 때문에 xargs를 통해 화장실은 바람직하지 않다 실행 전체 목록이 아닌 각 하위 목록의 총계입니다. "

따라서 이것을 시도하십시오 :

lc() { git ls-files -z ${1} | wc -l --files0-from=- ; } 

편집 : 당신 wc은 마지막 천년에서 왔고 그 옵션이 없기 때문에 여기에 awk"total"이라는 파일이 있다고 가정하고보다 휴대용 솔루션이 있습니다 . 의 출력을 필터링하여 행을 wc생략 total하고 대신 합산하여 마지막에 총계를 인쇄합니다.

내가 모르는 한 가지는 git별칭 구현에 내부 따옴표 $1$2내부 따옴표에 문제 가 있는지 여부 awk입니다.

lc() {
  git ls-files -z ${1} |
  xargs -0 wc -l |
  awk 'BEGIN { total=0; } { if (NF==2 && $2 == "total") total += $1; else print; } END { print total, "total"; }' ;
}

Linux를 실행하지 않고 Windows 용 Git의 git bash 프롬프트에 있습니다 .msysgit.github.io (msysgit).
Ehryk

확인. 너무을 xargs하고 wc당신이있는 거 실행 Cygwin에서에서인가? 출력을 붙여 넣을 수 있습니까 wc --version?
Mark Plotnick

그들은 완전한 cygwin 설치가 아닙니다 :$ wc --version wc (GNU textutils) 2.0 Written by Paul Rubin and David MacKenzie. Copyright (C) 1999 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Ehryk

Windows 실행 파일이 가득 찼습니다C:\Program Files (x86)\Git\bin\wc.exe
Ehryk

@Ehryk Msysgit은 Linux 도구의 포트이지만 이전 버전이있는 경향이 있으므로이 버전이 없을 수 있습니다 --files0-from.
Gilles 'SO- 악의

4

문제는 xargs명령을 여러 번 실행하는 것이므로 wc매번 총계를보고합니다. 몇 가지 옵션이 있으며 상황을 그대로 유지하고 wc출력을 구문 분석 할 수 있습니다.

git ls-files -z ${1} | xargs -0 wc -l | awk '/total/{k+=$1}END{print k,"total"}';

파일을 고양이로 만들 수 있습니다.

git ls-files -z ${1} | xargs -0 cat | wc -l

또는 당신은 xargs완전히 건너 뛸 수 있습니다 ( 여기 에서 적응 ) :

unset files i; while IFS= read -r -d $'\0' name; do 
 files[i++]="$name"; 
done < <(git ls-files -z ${1} ) && wc -l "${files[@]}"

파일 목록이 ARG_MAX 보다 길면 중단됩니다 .


-1
j=0; for i in *.php *.js *.css; do let j+=`wc -l $i | awk {'print $1'}`; done; echo $j;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.