![디렉토리에서 누락된 파일을 찾고 인쇄하는 방법은 무엇입니까?](https://linux55.com/image/156861/%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC%EC%97%90%EC%84%9C%20%EB%88%84%EB%9D%BD%EB%90%9C%20%ED%8C%8C%EC%9D%BC%EC%9D%84%20%EC%B0%BE%EA%B3%A0%20%EC%9D%B8%EC%87%84%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
.grid로 끝나는 파일이 포함된 상위 디렉터리의 모든 디렉터리를 찾아서 나열하고 싶습니다./work/user/folder1/*/*
find /work/user/folder1/*/*/ '!' -mindepth 1 -maxdepth 1 -name *.grid
다음으로 하고 싶은 일은 .grid로 끝나는 파일이 누락된 모든 디렉터리를 찾는 것입니다. 기본적으로 누락된 폴더를 인쇄하는 명령을 원합니다.
어떻게 해야 하나요?
답변1
find
전화를 걸 때 사용하세요 find
!
find . -type d \( -exec sh -c 'cd "$0"; find . \( -name . -o -prune \) -name "*.grid" | grep -q .' {} \; -o -print \)
이것은 POSIX를 준수합니다. 이 답변에 감사드립니다.
또한 이는 파일이나 디렉터리 이름에 공백, 특수 문자 또는 개행 문자가 있는지 여부에 관계없이 작동합니다. :)
(참고: 만약 당신이하다디렉토리 이름에 특수 문자나 개행 문자가 포함된 경우 -print
최종 main을 디렉토리에서 원하는 대로 변경해야 합니다. 왜냐하면 .만 사용하면 결과 인쇄 목록을 안전하게 구문 분석할 수 없기 때문입니다 -print
. )
다음은 가독성을 높이기 위해 오해의 소지가 있는 개행 문자가 추가된 버전입니다.
find . -type d \
\( \
-exec sh -c '
cd "$0";
find . \( -name . -o -prune \) -name "*.grid" |
grep -q .
' {} \; \
-o -print \
\)
답변2
1단계.) 적용 가능한 모든 디렉터리 목록을 만들고 영숫자순으로 정렬한 다음 중복 항목이 없는지 확인합니다. 임시 파일에 목록을 저장합니다.
find /work/user/folder1/ [...] -type d | sort | uniq > all_directories.txt
2단계.) 모든 파일 목록을 만듭니다 *.grid
.
find /work/user/folder1/ [...] -name *.grid > grid_files.txt
3단계.) 파일 목록을 살펴보고 *.grid
각 파일의 디렉터리 이름을 가져온 다음 다시 중복 항목이 없는지 확인하세요.
while read FILENAME
do
echo $(dirname "$FILENAME")
done < grid_files.txt | sort | uniq > dirs_with_gridfiles.txt
4단계.) 두 목록을 함께 실행하고 결과를 다시 정렬합니다. 이제 *.grid
파일이 포함된 디렉터리가 나열되어야 합니다.정확히각각 두 번씩, 디렉터리에 *.grid
파일이 없습니다.정확히각각 한 번씩. 따라서 uniq
중복되지 않은 행만 보고 하도록 알 수 있습니다 .
cat all_directories.txt dirs_with_gridfiles.txt | sort | uniq -u > dirs_with_no_gridfile.txt
당신은 그것을 얻습니다.
답변3
이는 2단계 솔루션입니다. 전반적으로 프로세스는 다음과 같습니다.
*.grid
기본 파일 이름과 목록을 제거하여 경로의 모든 파일을 찾습니다uniq
. 그러면 하나 이상의 파일이 포함된 모든 디렉토리의 목록이 제공됩니다*.grid
.
$ find /work/user/folder1/*/*/ -type f -name *.grid | sed -e 's-[^/]*$--' | sort | uniq > grid-dirs.txt
- 경로에서 모든 디렉터리를 찾고
grep
1단계에서 찾은 디렉터리를 필터링하는 데 사용합니다. 그러면*.grid
파일이 포함되어 있지 않은 모든 디렉터리 목록이 제공됩니다 .
$ find /work/user/folder1/*/*/ -type d | grep -Fvxf grid-dirs.txt
예를 들어 다음과 같이 가정합니다.
$ find /work
/work
/work/user
/work/user/folder1
/work/user/folder1/AA
/work/user/folder1/AA/AA
/work/user/folder1/AA/DD
/work/user/folder1/AA/CC
/work/user/folder1/AA/BB
/work/user/folder1/AA/BB/foo.grid
1단계 이후에는 grid-dirs.txt
다음과 같습니다.
/work/user/folder1/AA/BB/
2단계의 출력은 다음과 같습니다.
$ find /work/user/folder1/*/*/ -type d | grep -Fvxf grid-dirs.txt
/work/user/folder1/AA/AA/
/work/user/folder1/AA/CC/
/work/user/folder1/AA/DD/
답변4
Bash v4(또는 그 이상)를 사용하는 경우 *.grid
루프의 모든 파일과 모든 디렉터리를 통과하여 파일이 있는 디렉터리와 없는 디렉터리를 나열하는 내부 루프도 찾을 수 있다고 생각합니다. Bash v4의 경우 일반적으로 비활성화된 옵션 중 하나를 사용합니다.
(
# 'globstar' enables '**' expansions, which instructs
# the shell to search all and below recursively
shopt -s globstar
# Note that '**' is implicitly recursive, no need to specify
# depth. If you do want to specify precise depth, then use a
# '*/' for each wanted depth, like '*/*/*/' for 3 depths
for f in /work/user/folder1/**/*.grid; do
f="${f##*/}" # strip directory from found name
printf '\nNow looking for: %s\n' "$f"
# A simple '**/' returns directories only
for d in /work/user/folder1/**/; do
# simple existence test
[ -e "${d}${f}" ] && \
printf ' present in %s\n' "$d" || \
printf 'not present in %s\n' "$d"
done
done
)
불행히도 **
구문은 POSIX가 아닙니다.
그러나 검색해야 하는 정확한 깊이를 알고 있는 경우 해당 명령을 제거 shopt
하고 각 명령을 **/
반복으로 표현된 정확한 깊이로 변환하면 */
POSIX 셸에서도 잘 작동합니다.