스크립트 오류입니다. find 명령이 공백 문자가 있는 폴더를 건너뛰는 중입니다.

스크립트 오류입니다. find 명령이 공백 문자가 있는 폴더를 건너뛰는 중입니다.

디렉터리(및 하위 디렉터리)의 파일 수를 계산하는 스크립트가 필요합니다. 다음 스크립트를 가져와 필요에 맞게 변경했습니다.

공백 문자가 있는 폴더를 제외하고는 동일한 방식으로 작동합니다. 어딘가에 인용문이 누락된 것이 확실하지만 아직 알아낼 ​​수는 없습니다.

추가 정보

  • Linux 2.6.22.19-0.4-default(이 서버는 더 이상 생산되지 않습니다.)
  • GNU 버전 4.2.31 찾기
  • 디렉토리 이름을 바꿀 수 없습니다.

디렉토리 구조 예

.
..
01_infos
02_sent
03_inbox
04_public and private
197.
145.
329.
13.

스크립트

#!/bin/bash
# Write a script that will count the number of files in each of your subdirectories.
# -------------------------------------------------------------------------
# Copyright (c) 2001 nixCraft project <http://cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# -------------------------------------------------------------------------

START=$HOME

# change your directory to command line if passed
# otherwise use home directory
[ $# -eq 1 ] && START=$1 || :

if [ ! -d $START ]
then
        echo "$START not a directory!"
        exit 1
fi

# use find command to get all subdirs name in DIRS variable
DIRS=$(find "$START" -type d)

# loop thought each dir to get the number of files in each of subdir
for d in $DIRS
do
        echo "$d directory has $(find "$d" -maxdepth 1 -regex '.*\.' -type f | wc -l) files" || :
done

산출

./01_infos directory has 1 files
./02_sent directory has 9 files
./03_inbox has 4 files
find: ./04_public: No such file or directory

답변1

일부 큰따옴표가 누락되었습니다(변수 대체에는 항상 큰따옴표를 사용하십시오. $foo변수 대체 및 명령 대체에는 항상 큰따옴표를 사용하십시오.$(foo), 안전하게 떠날 수 있는 이유와 떠나야 하는 이유를 모르는 경우). 하지만 그게 전부는 아닙니다.

if [ ! -d $START ]

해야 한다 if [ ! -d "$START" ].

DIRS=$(find "$START" -type d)

이때 DIRS재귀는 시작 디렉터리와 그 하위 디렉터리의 이름으로 구성되며 그 사이에는 줄바꿈이 포함됩니다. 따라서 개행 문자가 포함된 디렉터리 이름이 있으면 길을 잃게 됩니다. 디렉터리 이름에서 어떤 개행 문자가 나오고 어떤 것이 구분 기호인지 아는 것이 불가능합니다. 파일 이름에 개행 문자가 없다는 것을 알고 있으면 출력을 구문 분석할 수 있지만 find어떻게 알 수 있습니까?

그건 그렇고, 여기에는 큰따옴표가 없어도 괜찮습니다. $(…)왜냐하면 이것은 변수 할당이고 할당 내의 대체는 암시적으로 보호되기 때문입니다. 그러나 export DIRS=$(…)유사하게 보호되지는 않습니다. 쉘 스크립팅에 능숙하지 않은 한 따옴표를 사용하는 것이 가장 좋으며 스크립트를 유지 관리하는 모든 사람도 마찬가지입니다.

for d in $DIRS

여기서 실패합니다. $DIRS단어로 분리하려고 하므로 큰따옴표를 넣을 수 없지만 $DIRS모든 요소가 함께 연결되므로 큰따옴표가 필요하며, 따옴표를 넣지 않으면 파일 이름 안의 공백이 구분자가 됩니다.


일반적으로 를 사용할 때는 옵션 find과 함께 처리 명령을 호출하도록 해야 합니다 -exec. 파일 이름을 엄격하게 제어하지 않는 한 출력을 구문 분석하지 마십시오 find. 모호합니다.

find "$START" -type d -exec sh -c '
    echo "$0 directory has $(find "$0" -maxdepth 1 -regex ".*\\." -type f -printf \\n | wc -l) files whose name ends with ."
' {} \;

포함된 find명령에서 구문 분석된 출력에 find개행 문자가 포함되어 있으면 계산이 꺼집니다.

답변2

이건 어때?

find . -type d -exec sh -c '/bin/echo -n "{}"; find "{}" -maxdepth 1 -regex ".*\." -type f | wc -l; ' \;

출력은 그다지 훌륭하지는 않지만 스크립팅이 필요하지 않으며 공백 및 기타 영숫자가 아닌 문자가 있는 디렉터리에서 작동합니다.

답변3

고전적인 인용 오류가 있습니다. for 루프를 다음과 같이 수정하세요.

for d in "$DIRS"

또는 find출력을 직접 입력할 수 있습니다. 예:

find "$START" -type d | while read d
do # and so on...

그런데 이 비트는 반환 값이 항상 0이므로 || :완전히 중복됩니다 .echo

관련 정보