여러 폴더를 반복하고 bash에서 비슷한 패턴을 가진 파일을 계산합니다.

여러 폴더를 반복하고 bash에서 비슷한 패턴을 가진 파일을 계산합니다.

여러 개의 폴더가 있는데 각 폴더에는 여러 .nc파일이 포함되어 있습니다. 모든 폴더를 반복하고 cdo각 폴더에 대해 비슷한 패턴을 가진 파일에 대해 일부 계산(병합 시간)을 수행하고 싶습니다. 지금까지 나는 다음과 같이 썼다:

for dir in /mnt/meteo_a/africa_cordex/historical/0.44/pr/*/     
do 
 dir=${dir%*/}
 echo ${dir##*/} 
 export dir
 cd $dir
 pwd
  for f in `find . -type f -regex /(.*?\day)/*`
  cdo mergetiem io
  done
done

각 폴더의 파일 이름은 다음과 같습니다.

pr_AFR-44_CNRM-CERFACS-CNRM-CM5_historical_r1i1p1_CLMcom-CCLM4-8-17_v1_day_19500101-19501231.nc
pr_AFR-44_CNRM-CERFACS-CNRM-CM5_historical_r1i1p1_CLMcom-CCLM4-8-17_v1_day_19510101-19551231.nc
pr_AFR-44_ICHEC-EC-EARTH_historical_r12i1p1_CLMcom-CCLM4-8-17_v1_day_19491201-19501231.nc
pr_AFR-44_ICHEC-EC-EARTH_historical_r12i1p1_CLMcom-CCLM4-8-17_v1_day_19510101-19551231.nc

비슷한 패턴을 가진 모든 이전 파일에 mergetime CDO 명령을 적용하고 싶습니다 _day_.

처음 두 파일과 마지막 두 파일을 병합하고 싶습니다. 보다 구체적으로 다음으로 시작하는 파일을 병합합니다.

"pr_AFR-44_CNRM-CERFACS-CNRM-CM5_historical_r1i1p1_CLMcom-CCLM4-8-17_v1_" 

다음으로 시작하는 파일도 병합합니다.

"pr_AFR-44_ICHEC-EC-EARTH_historical_r12i1p1_CLMcom-CCLM4-8-17_v1"

병합된 시간의 출력은 다음과 같습니다.

 {pattern}_mergetime.nc 

답변1

이 스크립트 조각은 샘플 파일에 작동합니다.

for file in *.nc
do 
    echo "$file"
done | sed 's/_day_.*//' | sort -u | while read -r pattern
do
    cdo mergetime "${pattern}"* "${pattern}_mergetime.nc"
done

설명하다:

  • 루프는 한 줄에 하나의 파일 이름을 for인쇄합니다 .echo
  • sed명령은 _day_이후의 모든 문자를 제거합니다.
  • sort -u부분적인 파일 이름을 정렬하고 중복된 파일을 제거합니다.
  • while read -r pattern한 줄에 하나의 패턴을 읽고 패턴을 반복합니다.
  • "${pattern}"*셸에서 이 패턴으로 시작하는 모든 파일 이름으로 확장됩니다.

for루핑보다 낫 echo습니다.

find . -maxdepth 1 -type f -name '*.nc'

*.nc그러면 하위 디렉터리를 제외하고 현재 디렉터리에서 일치하는 모든 파일 이름이 인쇄됩니다 .

질문의 스크립트와 유사하게 이를 모든 하위 디렉터리에 대한 루프와 결합할 수 있습니다.

for dir in /mnt/meteo_a/africa_cordex/historical/0.44/pr/*/     
do 
    dir=${dir%*/}
    echo ${dir##*/} 
    export dir
    pushd $dir
    pwd

    find . -maxdepth 1 -type f -name '*.nc' | sed 's/_day_.*//' | sort -u | while read -r pattern
    do
        cdo mergetime "${pattern}"* "${pattern}_mergetime.nc"
    done

    popd
done

대신 나중에 다시 돌아갈 수 있도록 허용 cd하는 것이 좋습니다 .pushdpopd

for디렉토리의 루프를 추가된 루프로 바꿀 수도 있습니다.find

find /mnt/meteo_a/africa_cordex/historical/0.44/pr -maxdepth 1 -mindepth 1 -type d | while read dir
do
    pushd "$dir"

    find . -maxdepth 1 -type f -name '*.nc' | sed 's/_day_.*//' | sort -u | while read -r pattern
    do
        cdo mergetime "${pattern}"* "${pattern}_mergetime.nc"
    done

    popd
done

관련 정보