for 루프의 glob 연산자 관련 문제

for 루프의 glob 연산자 관련 문제

/home 디렉토리의 모든 파일을 반복적으로 반복하려고 합니다. 각 파일에서 일부 Linux 명령을 실행하고 싶습니다. 그래서 저는 다음과 같은 for 루프를 사용하고 있습니다.

for i in /home/**/*

또한 다음 명령문으로 스크립트를 시작합니다.

  • shopt -s 글로스타
  • shopt -s nullglob

하지만 for 루프에 갇히게 됩니다. 너무 많은 파일을 처리하는 데 문제가 있을 수 있습니다. for 루프에 다른 디렉터리(파일 수가 적은)를 제공하면 올바르게 통과합니다.

또 무엇을 시도할 수 있나요?

전체 코드:

#!/bin/bash

shopt -s globstar
shopt -s nullglob
echo "ggg"
for i in /home/**/*
do
    NAME=${i}
    echo "It's there." $NAME
    if [ -f "$i" ]; then
        echo "It's there." $NAME
        printf "\n\n"
    fi
done

답변1

쉘에는 확장 모드가 필요합니다/home/**/* 완전히루프의 첫 번째 반복을 시작하기 전에. 파일이 많으면주기가 실제로 시작되기까지 자연스럽게 시간이 걸립니다. 예제에서 셸 프로세스를 관찰하면 top그 아래에 있는 모든 파일과 디렉터리의 목록이 작성됨에 따라 메모리 소비가 점차 증가한다는 것을 알 수 있습니다 /home.

디렉토리 구조의 일반 파일 수를 계산하려면 를 사용하는 것이 가장 좋습니다 find.

find /home -type f -printf '\n' | wc -l

그러면 아래의 각 일반 파일에 대해 한 줄의 출력이 인쇄되고 /homewc수를 계산하여 끝에 합계가 제공됩니다.

숨겨진 파일을 방지하려면:

find /home ! -name '.*' -type f -printf '\n' | wc -l

또한 디렉토리를 숨기지 마십시오(쉘 루프도 이 작업을 수행합니다).

find /home -name '.*' -prune -o -type f -printf '\n' | wc -l

wc -l출력에서 경로 이름을 계산하는 대신 빈 줄을 계산하는 이유 -print는 경로 이름에 개행 문자가 포함될 수 있으며, 이 경우 wc -l계산 오류가 발생할 수 있기 때문입니다.


심볼릭 링크와 관련하여: 쉘 루프는 심볼릭 링크를 따르므로 심볼릭 링크된 디렉터리가 있으면 루프가 해당 디렉터리로 들어가고, 일반 파일을 가리키는 심볼릭 링크가 있는 경우 루프는 해당 디렉터리를 계산합니다.

위의 솔루션 find아니요심볼릭 링크를 따르십시오. 이 -L옵션을 사용하여 find유사한 동작을 얻을 수 있습니다.

find -L /home -type f -printf '\n' | wc -l

GNU 사용자가 아닌 사용자도 find사용할 수 있습니다 .-exec echo \;-printf '\n'

관련 정보