CSV 파일에 나열된 패턴이 포함된 폴더를 검색하여 다른 위치에 복사하세요.

CSV 파일에 나열된 패턴이 포함된 폴더를 검색하여 다른 위치에 복사하세요.

파일이 포함된 폴더가 수천 개 있는데 그 중 일부를 다른 디렉터리에 복사하고 싶습니다. 폴더 이름의 일부를 포함하는 두 개의 열이 있는 파일이 있습니다 .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/$pat2>/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 

관련 정보