폴더 이름 목록이 포함된 텍스트 파일을 반복하고 해당 폴더 중 특정 경로(이 경우에는 2021
.
내 list.txt 파일에는 다음과 같은 목록이 포함되어 있습니다.
100001
100002
100003
100004
...
2021
이름을 확인하려는 하위 폴더가 포함된 디렉터리(소위)가 있습니다.
100001
100002
100004
...
이제 이 예에서 스크립트는 폴더가 100003
누락되었음을 나타내야 합니다. 이 스크립트의 목적은 단순히 텍스트 파일에 나열된 폴더가 경로에서 누락되었는지 찾는 것입니다.
지금까지 나는 다음을 가지고 있습니다 :
while IFS= read -r line; do
if [[ ! -d "2021/$line" ]]; then
echo $line is missing
fi
done <<< $(cat list.txt)
하지만 이 코드는 디렉토리에 있는 모든 폴더를 인쇄할 뿐이 2021
므로 명령문에 문제가 있는 것으로 추측되지만 IF
알 수 없습니다.
답변1
폴더가 포함된 경로 외부에서 쉘 스크립트를 실행하고 있다고 가정합니다 2021
.
다음과 같은 구조로:
$> tree
#output:
.
├── 2021
│ ├── 100000
│ ├── 100001
│ ├── 100002
│ ├── 100003
│ ├── 100006
│ ├── 100007
│ ├── 100008
│ ├── 100009
│ ├── 100010
│ ├── 100011
│ ├── 100019
│ ├── 100020
├── list.txt
└── script
아무것도 변경하지 않고 현재 스크립트를 실행할 수 있어야 합니다. 다음을 사용하세요../script
문제는 script
스크립트 디렉토리 외부에서 코드를 실행하면 코드가 성공적으로 실행되지 않는다는 것입니다. 따라서 스크립트를 다음과 같이 변경하는 것이 좋습니다.
#!/bin/bash
filepath="$(dirname $(readlink -f $0) )"
cd $filepath
while read -r line; do
if [[ ! -d "2021/$line" ]]; then
echo $line is missing
fi
done <<< $(cat list.txt)
#Or:
# done < /paht/to/list.txt
나는 그것을 삭제했다 IFS=
. 왜 가지고 있는지는 모르겠지만 꼭 사용해야 한다면 추가하세요.
따라서 모든 디렉터리에서 스크립트를 실행할 수 있습니다../path/to/dir/script
다음 명령을 사용하여 누락된 디렉터리를 가져올 수도 있습니다.
#With this code you will get only the missing dirs. The text 'is missing'
#won't appear here
diff --new-line-format="" --unchanged-line-format="" <(sort /path/to/list.txt) <(find . -maxdepth 1 -type d ! -path . -printf '%P\n' | sort)
파일이 실제로 정렬된 경우 단순으로 list.txt
변경할 수 있습니다.<(sort /path/to/list.txt)
/path/to/list.txt
2021
위의 코드를 사용하는 경우 디렉토리 아래에 배치 하고 /path/to/list.txt
실제 경로로 변경하십시오.list.txt
답변2
몇 시간 동안 문제를 검색한 끝에 마침내 해결책을 찾았습니다.
문제는 파일이 원래 Windows OS에서 생성된 다음 bash 쉘에서 사용된다는 것입니다. 즉, Windows에서는 줄 바꿈과 캐리지 리턴으로 끝나지만 Unix에서는 단일 줄 바꿈으로만 끝납니다.
IF
따라서 파일의 이름을 폴더의 이름과 비교할 때 목록 파일의 이름에 누구에게도 표시되지 않는 추가 캐리지 리턴이 있기 때문에 분명히 일치하는 것이 불가능하다고 추측합니다 .
그래서 유닉스에서 파일을 다시 만들었고 이제 예상했던 결과를 완벽하게 얻었습니다. 도움을 주신 모든 분들께 감사드립니다.
답변3
저는 bash 대신 zsh를 사용합니다. 옵션으로 우수한 glob과 배열 연결( ${A:*B}
) 및 빼기( ${A:|B}
) 연산자를 사용할 수 있습니다.
#! /bin/zsh -
list=path/to/list.txt
dir=path/to/2021
# or list=${1?} dir=${2?}
# for instance to pass those as arguments to the script
expected=( ${(f)"$(<$list)"} )
# or expected=( ${(f)"$(dos2unix < $list)"} )
# if that file is in MS DOS/Windows format
got=( $dir/*(ND/:t) )
# or got=( $dir/*(ND-/:t) )
# to also consider symlinks to directories like your [[ -d ... ]] does
report() {
if (( $# > 1 )); then
print -rC1 -- $1: ' - '$^@[2,-1]
else
print -r -- $1: none
fi
}
report Found ${expected:*got}
report Missing ${expected:|got}
report Unexpected ${got:|expected}