나는 거대한 폴더 트리를 가지고 있으며, 각 폴더에는 약 3레벨 아래의 여러 하위 디렉터리가 있습니다. 다음은 레벨이 하나만 있는 예입니다.
$ tree
.
|-- AB.txt
|-- CD.txt
|-- destination_folder
|-- spreadsheet.txt
`-- subdirectory
`-- EF.txt
2 directories, 4 files
다음과 같은 관심 있는 파일 이름 목록이 있습니다 spreadsheet.txt
.
$ cat spreadsheet.txt
AB.txt
CD.txt
EF.txt
spreadsheet.txt
폴더에 나타나는 모든 파일을 복사하고 싶습니다 destination_folder
. 도움을 주셔서 감사합니다! 나는 이것이 관련될 것이라고 생각했지만 find
그것을 cp
알아낼 수는 없는 것 같습니다.
답변1
find
파일 이름에 개행 문자가 포함되어 있지 않다고 가정하고 파일 이름당 한 번 실행합니다 .
#!/bin/sh
mkdir -p destination_folder || exit 1
while IFS= read -r name; do
find . -path ./destination_folder -prune -o \
-type f -name "$name" -exec cp {} destination_folder \;
done <spreadsheet.txt
먼저 현재 디렉터리 내에 대상 디렉터리를 생성합니다(또는 실패 시 종료됩니다). 그런 다음 입력 파일을 한 줄씩 읽고 호출하여 find
해당 이름을 가진 일반 파일을 찾습니다. 검색에서 대상 디렉토리를 발견할 때마다 다음을 find
사용하여 명시적으로 이를 피합니다.-prune
올바른 이름의 파일을 찾으면 해당 파일이 대상 디렉터리에 복사됩니다. 여러 파일의 이름이 같은 경우 복사본을 destination_folder
덮어씁니다.
현재 디렉터리가 크거나 파일 이름 목록이 길면(그러나 수천 줄은 아님) 작업 속도가 느려집니다. 그래서 우리는하나의우리에게 전화하세요 find
. 아래 코드는 bash
배열을 사용하므로 예를 들어 실행된다고 가정합니다 .
#!/bin/bash
mkdir -p destination_folder || exit 1
names=()
while IFS= read -r name; do
names+=( -o -name "$name" )
done <spreadsheet.txt
find . -path ./destination_folder -prune -o \
\( "${names[@]:1}" \) -type f -exec cp -t destination_folder {} +
여기서는 발견된 파일당 한 번이 아닌 가능한 한 적은 수의 호출을 수행하기 위해 cp -t
(GNU cp
확장)을 사용하기로 결정했습니다 .cp
위의 코드는 names
최종적으로 find
. 귀하의 질문에 나온 예에 따르면 위 코드 끝에서 실행되는 실제 명령은 다음과 같습니다.
find . -path ./destination_folder -prune -o '(' -name AB.txt -o -name CD.txt -o -name EF.txt ')' -type f -exec cp -t destination_folder '{}' +
대상 디렉토리에서 파일 이름 충돌 문제를 방지하려면 GNU 를 사용하는 경우(예: Linux 시스템에서) 또는 옵션을 cp
사용하십시오 .cp
-b
--backup
Linux가 아닌 시스템에서는 일반적으로 cp
패키지 관리자를 통해 GNU coreutils를 설치한 후 GNU를 사용할 수 있습니다.gcp
마지막 스크립트 /bin/sh
(무제한 배열):
#!/bin/sh
mkdir -p destination_folder || exit 1
set --
while IFS= read -r name; do
set -- -o -name "$name" "$@"
done <spreadsheet.txt
shift
find . -path ./destination_folder -prune -o \
\( "$@" \) -type f -exec cp -t destination_folder {} +
답변2
간단한 for 루프:
for filename in $(cat spreadsheet.txt)
do
find . -name "$filename" -exec cp {} /destination/folder \;
done