오늘의 시간별 파일을 읽고 병합하는 방법은 무엇입니까?

오늘의 시간별 파일을 읽고 병합하는 방법은 무엇입니까?

Netcdf 파일 폴더가 있습니다. 이 파일은 한 달에 6시간 동안의 바람 파일입니다. 모든 파일을 병합하고 싶습니다. 시간별로 파일을 읽어 결합하는 쉘 스크립트를 만드는 방법을 모르겠습니다. 도와주세요.

anal_00z20230118.nc
anal_00z20230119.nc
anal_00z20230120.nc
anal_00z20230121.nc
anal_00z20230122.nc
anal_00z20230123.nc
anal_00z20230124.nc
anal_00z20230125.nc
anal_00z20230126.nc
anal_00z20230127.nc
anal_00z20230128.nc
anal_00z20230129.nc
anal_00z20230130.nc
anal_00z20230131.nc
anal_06z20230118.nc
anal_06z20230119.nc
anal_06z20230120.nc
anal_06z20230121.nc
anal_06z20230122.nc
anal_06z20230123.nc
anal_06z20230124.nc
anal_06z20230125.nc
anal_06z20230126.nc
anal_06z20230127.nc
anal_06z20230128.nc
anal_06z20230129.nc
anal_06z20230130.nc
anal_12z20230118.nc
anal_12z20230119.nc
anal_12z20230120.nc
anal_12z20230121.nc
anal_12z20230122.nc
anal_12z20230123.nc
anal_12z20230124.nc
anal_12z20230125.nc
anal_12z20230126.nc
anal_12z20230127.nc
anal_12z20230128.nc
anal_12z20230129.nc
anal_12z20230130.nc
anal_18z20230118.nc
anal_18z20230119.nc
anal_18z20230120.nc
anal_18z20230121.nc
anal_18z20230122.nc
anal_18z20230123.nc
anal_18z20230124.nc
anal_18z20230125.nc
anal_18z20230126.nc
anal_18z20230127.nc
anal_18z20230128.nc
anal_18z20230129.nc
anal_18z20230130.nc

답변1

GNU awk 및 zsh 사용:

set -o extendedglob
LC_ALL=C gawk '
  BEGINFILE {out = gensub(/(.*_)[0-9]{2}z/, "\\1", FILENAME) ".combined"}
  {print > out}' ./*_(00|06|12|18)z[0-9](#c8).nc

anal_20230130.nc.combined각 파일 세트에 대해 하나씩 작성됩니다 anal_XXz20230130.nc.

에서는 동등한 bash글로브 패턴이 필요합니다../*_@(00|06|12|18)z[0123456789][0123456789][0123456789][0123456789][0123456789][0123456789][0123456789][0123456789].ncshopt -s extglob failglob

및 에서 bashglob zsh은 어휘적으로 확장되므로 *_00z*파일은 *_06z*파일 자체 앞에 나타나며 *_12z*파일 자체 앞에 나타납니다 *_18z*.

파일 수가 많은 경우 execve()매개변수 + 환경 크기 제한이 발생하여"매개변수 목록이 너무 깁니다"실수.

print -rNC1이는 목록을 zsh의 내장 함수에 전달하고(따라서 execve()가 포함되지 않음) NUL로 구분하여 전달하여 목록을 인쇄함으로써 피할 수 있습니다 gawk.

set -o extendedglob
print -rNC1 ./*_(00|06|12|18)z[0-9](#c8).nc(N) |
  LC_ALL=C gawk '
    !start {ARGV[ARGC++] = $0; next}
    BEGINFILE {out = gensub(/(.*_)[0-9]{2}z/, "\\1", FILENAME) ".combined"}
    {print > out}' RS='\0' - start=1 RS='\n'

bash아니요 print -rNC1. 하지만 다음 함수를 사용하여 시뮬레이션할 수 있습니다.

print0() { [ "$#" -eq 0 ] || printf '%s\0' "$@"; }

대신 glob 한정자와 동등한 것을 nullglob얻으려면 사용하십시오 .failglobzshN

이러한 6시간짜리 파일이 줄 중간에서 분할된 경우(예: 줄 바꿈이 아닌 다음으로 anal_00z20230130.nc끝나고 로 시작하는 경우 , 결합된 파일은 읽는 각 레코드 뒤에 1을 추가 하므로 대신 , 짝수 이것이 원하는 것이 아니거나 파일이 텍스트 파일이 아닌 경우 .unix.staanal_06z20230130.ncckexchange.comunix.sta<newline>ckexchange.comunix.stackexchange.comgawkORSprintprintf "%s", $0 RT

관련 정보