파일이 포함된 폴더가 수천 개 있는데 그 중 일부를 다른 디렉터리에 복사하고 싶습니다. 폴더 이름의 일부를 포함하는 두 개의 열이 있는 파일이 있습니다 .csv
(폴더에는 하나의 문자열 값이 포함되어 있지만 둘 다 포함되지는 않음).
- 폴더 이름의 예:
PLASMA_32150129_B5/ PLASMA_AAA3891784_B3/ ...
- CSV 파일에는 헤더가 없으며 필드는 다음으로 구분됩니다
,
.32150129,AAA0616938 32140203,AAA3891784 32140204,AAA0617237 32140205,AAA0617261 32140206,AAA0617285 ...
- 나는 이 작은 스크립트를 출발점으로 찾았습니다.
while IFS=, read -r file rest do find /path/to/Main_directory -type d -name "${file}" -exec cp '{}' /path/to/New_directory/ \; done < mylist.csv
이제 지정해야 합니다.
- csv 값은 단지 패턴(예
*_32150129 _*
: ) 일 뿐이며 - 먼저 첫 번째 열의 패턴을 시도하고, 일치하는 항목이 생성되지 않으면 다른 열을 시도하고 싶습니다.
가능합니까?
감사합니다!
답변1
실제로 하나의 열만 일치할 수 있다고 가정하면 "OR" 유형 접근 방식이 가능할 수 있습니다. 이렇게 하려면 스크립트를 약간 수정하면 됩니다.
while IFS=, read -r pattern1 pattern2
do
find /path/to/start -type d \( -name "*_${pattern1}_*" -o -name "*_${pattern2}_*" \) -exec cp -r '{}' /path/to/target \;
done < filelist.csv
- 연산자는
-o
두 이름 패턴 중 하나가 일치하는지 확인합니다. 두 개가 일치할 수 없는 한(전제 조건 참조) 이는 "첫 번째가 존재하지 않으면 두 번째"와 동일합니다. - 괄호(셸 해석을 방지하기 위해 이스케이프됨)는 올바른 연산자 우선순위를 보장하는 데 사용됩니다.
- 쉘 매개변수를
-name
큰따옴표로 묶으면*
다음이 보장됩니다.말 그대로 바로 거기전역 확장이 필요하지 않으며(find
쉘에 전달되기 전이 아닌 검색 중에 패턴 일치가 수행되도록 해야 함find
) 쉘 변수${pattern1}
및${pattern2}
확장이 계속 발생하도록 허용합니다. - 디렉터리와 그 내용을 복사하려면
-r
이 옵션을 사용해야 합니다.cp
답변2
가장 간단하고 조잡한 방법을 사용해 본 적이 있다면 효과가 있을 것입니다.하나파일의 모든 패턴을 일치시키고 셸이 작업을 수행하도록 합니다.
tr , '\n' < mylist.csv |
while read pat; do cp -r source_dir/*"$pat"* target_dir/ 2>/dev/null; done
먼저 모든 것을 줄 바꿈 ,
으로 변환하십시오 file.csv
.
$ tr , '\n' < file.csv
32150129
AAA0616938
32140203
AAA3891784
32140204
AAA0617237
32140205
AAA0617261
32140206
AAA0617285
그런 다음 각 패턴을 변수로 읽고 (즉, match 의 모든 항목 ) 대상 디렉터리에 $pat
맹목적으로 복사합니다 . 일치하는 항목이 없으면 아무 것도 복사되지 않으며 오류 메시지가 표시되며 이를 위해 Discard 를 사용할 수 있습니다 .source_dir/*$pat*
source_dir/
$pat
2>/dev/null
보다 복잡한 접근 방식을 위해서는 다음과 같이 할 수 있습니다.
## make sure we don't match the glob pattern itself when no matching
## directories are found
shopt -s nullglob
mainTargetDir=/path/to/Main_directory
sourceDir=/path/to/start
while IFS=, read -r f1 f2; do
sourceFiles=("$sourceDir"/*"$f1"* "$sourceDir"/*"$f2"*)
[ -z "${sourceFiles[@]}" ] ||
cp -r -- "${sourceFiles[@]}" $mainTargetDir
done < file.csv