파일 이름이 포함된 조회 파일이 있습니다. 또한 파일이 포함된 디렉토리가 있는데, 그 중 일부는 디렉토리의 특정 이름에 해당하는 이름을 가지고 있습니다.
내가 어떻게 할 수있는:
- 정확히 일치하는 파일을 새 디렉터리로 이동하거나
- 기존 디렉터리에서 일치하지 않는 파일을 제거합니다.
또한 최상위 디렉터리와 해당 하위 디렉터리를 통해 이 작업을 반복적으로 수행하려면 어떻게 해야 합니까?
답변1
어쩌면 다음과 같은 것일 수도 있습니다.
sed -e 's;^.*$;\^&\$; list-of-names > list-of-patterns
rm $(find . -type f | grep -v -f list-of-patterns)
파일 이름에 쉘이 특별하다고 간주하는 공백이나 문자가 포함되어 있으면 확실히 깨질 수 있으니 주의하세요. 실제로 실행하기 전에 무엇이 제거되는지 확인하십시오!
(스키마 파일을 우회하는 방법이 있을 수도 있지만 전혀 보이지 않습니다.)
답변2
다음 bash 스크립트(경고: 테스트되지 않음!)는 파일을 아래에서 /directory/with/the/files
아래로 이동합니다 /matched/files
. /path/to/lookup.file
이름 별로만 파일을 이동합니다(디렉터리 제외). 에 디렉토리에 대한 심볼릭 링크가 있는 경우 /directory/with/the/files
디렉토리 자체인 것처럼 재귀적으로 탐색됩니다.
#!/bin/bash
shopt -s globstar
set -f; IFS=$'\n'
typeset -A filenames
for x in $(cat /path/to/lookup.file); do filenames[$x]=1; done
set +f; unset IFS
cd /directory/with/the/files
for x in ./**; do
if [[ -d "$x/." ]]; then
: # skip directories and symbolic links to directories
elif [[ -n ${filenames[${x##*/}]} ]]; then
# the file is matched, move it under /matched/files
mkdir -p "/matched/files/${x%/*}"
mv "$x" "/matched/files/$x"
else
# the file isn't matched
:
fi
done
설명하다:
shopt -s globstar
만들다**
전반적인 상황디렉터리를 재귀적으로 탐색합니다.set -f; IFS=$'\n'
와일드카드를 끄고 새 줄을 유일한 단어 구분 기호로 설정하여$(cat /path/to/lookup/files)
인용되지 않은 명령 대체가 새 줄에서만 분할되도록 합니다.filenames
는연관 배열.for x in ./**
$x
디렉토리 부분은 항상 포함되며(이런 방식으로 디렉토리${x%/*}
부분은 최상위 디렉토리를 의미함) 로 시작하지 않습니다(따라서 옵션으로 취급될 위험이 없습니다).$x
.
-
${x##*/}
파일 이름 부분$x
, 즉$x
디렉터리 부분 없이 확장됩니다.