파일 카운트가있는 폴더를 나열하는 UNIX 명령
문제
현재 레벨 (하위 폴더 포함)에서 폴더 목록을 얻고 폴더 이름과 폴더의 파일 수를 인쇄하려고합니다 (가능하면 *.jpg로 필터링).
표준 배쉬 쉘에서 가능합니까? ls -l
파일 카운트를 제외한 모든 것에 대해 인쇄 :)
해결책
나는 이것을 생각해 냈다 :
find -maxdepth 1 -type d | while read dir; do
count=$(find "$dir" -maxdepth 1 -iname \*.jpg | wc -l)
echo "$dir ; $count"
done
두 번째 -maxdepth 1
JPG 파일의 디렉토리 내에서 검색이 하위 다이렉터를 고려하여 재귀 적이어야하는 경우. 파일 이름 만 고려합니다. 파일 이름을 바꾸고 JPG 사진이라고 숨길 수 있습니다. 당신은 사용할 수 있습니다 file
대신 내용을 추측하도록 명령 (이제 재귀 적으로 검색).
find -mindepth 1 -maxdepth 1 -type d | while read dir; do
count=$(find "$dir" -type f | xargs file -b --mime-type |
grep 'image/jpeg' | wc -l)
echo "$dir ; $count"
done
그러나 파일의 일부를 읽고 결국에는 포함 된 내용을 해석해야하므로 훨씬 느립니다 (운이 좋으면 파일 시작시 마술 ID를 찾습니다). 그만큼 -mindepth 1
인쇄를 방지합니다 .
(현재 디렉토리) 검색하는 다른 디렉토리로서.
다른 팁
나는 이미 나 자신의 비슷한 대본을 알아 낸 후이 질문을 발견했습니다. 그것은 당신의 상태에 맞는 것처럼 보이고 매우 유연하기 때문에 답으로 추가 할 것이라고 생각했습니다.
장점 :
- 그룹화 할 수 있습니다 모든 깊이 (0
.
, 1 레벨 하위 디렉토리 등 1) - 꽤 출력을 인쇄합니다
- 루프가없고 단 하나만
find
명령, 큰 디렉토리에서는 조금 더 빠릅니다. - 사용자 정의 필터를 추가하도록 여전히 조정할 수 있습니다 (비수체 적, 파일 이름 패턴을 만들기 위해 MaxDepth)
원시 코드 :
find -P . -type f | rev | cut -d/ -f2- | rev | \
cut -d/ -f1-2 | cut -d/ -f2- | sort | uniq -c
함수로 싸서 설명했습니다.
fc() {
# Usage: fc [depth >= 0, default 1]
# 1. List all files, not following symlinks.
# (Add filters like -maxdepth 1 or -iname='*.jpg' here.)
# 2. Cut off filenames in bulk. Reverse and chop to the
# first / (remove filename). Reverse back.
# 3. Cut everything after the specified depth, so that each line
# contains only the relevant directory path
# 4. Cut off the preceeding '.' unless that's all there is.
# 5. Sort and group to unique lines with count.
find -P . -type f \
| rev | cut -d/ -f2- | rev \
| cut -d/ -f1-$((${1:-1}+1)) \
| cut -d/ -f2- \
| sort | uniq -c
}
다음과 같은 출력을 생성합니다.
$ fc 0
1668 .
$ fc # depth of 1 is default
6 .
3 .ssh
11 Desktop
44 Downloads
1054 Music
550 Pictures
물론 숫자를 먼저 사용하면 파이프를 할 수 있습니다. sort
:
$ fc | sort
3 .ssh
6 .
11 Desktop
44 Downloads
550 Pictures
1054 Music
광산은 명령 줄에서 입력하는 것이 더 빠릅니다. :)
다른 제안은 다음과 같은 실질적인 이점을 제공합니까?
find -name '*.jpg' | wc -l # recursive
find -maxdepth 1 -name '*.jpg' | wc -l # current directory only
#!/bin/bash
for dir in `find . -type d | grep -v "\.$"`; do
echo $dir
ls $dir/*.jpg | wc -l
done;
외부 명령없이 수행 할 수 있습니다.
for d in */; do
set -- "$d"*.jpg
printf "%s: %d\n" "${d%/}" "$#"
done
또는 사용할 수 있습니다 어색한 (nawk 또는 /usr/xpg4/bin/awk ~에 Solaris):
printf "%s\n" */*jpg |
awk -F\/ 'END {
for (d in _)
print d ":",_[d]
}
{ _[$1]++ }'