복붙노트

[HADOOP] 지난 24 시간 동안 HDFS에서 여러 디렉토리에서 로컬로 파일을 복사

HADOOP

지난 24 시간 동안 HDFS에서 여러 디렉토리에서 로컬로 파일을 복사

나는 지역에 HDFS에서 데이터를 가져 오는 문제가있다. 나는 예를 들어 있습니다 :

/path/to/folder/report1/report1_2019_03_24-03_10*.csv
/path/to/folder/report1/report1_2019_03_24-04_12*.csv
...
/path/to/folder/report1/report1_2019_03_25-05_12*.csv
/path/to/folder/report1/report1_2019_03_25-06_12*.csv
/path/to/folder/report1/report1_2019_03_25-07_11*.csv
/path/to/folder/report1/report1_2019_03_25-08_13*.csv
/path/to/folder/report2/report2_out_2019_03_25-05_12*.csv
/path/to/folder/report2/report2_out_2019_03_25-06_11*.csv
/path/to/folder/report3/report3_TH_2019_03_25-05_12*.csv

그래서 나는이 각 폴더에 입력해야합니다 (보고서 1, report2, REPORT3 ...하지만 그 모든는 "보고서"로 시작) 다음 지역으로 이전 24시간 복사본에서 그리고 그 4 매일 아침 수행해야 CSV 파일 및 오전 (I crontab을 가진이를 예약 할 수 있습니다). 문제는 내가 파일을 반복, 인수로서 타임 스탬프를 전달하는 방법을 모르는 것입니다.

나는이 같은 뭔가 시도 (스택 오버플로에 있음)

/datalake/hadoop/bin/hadoop fs -ls /path/to/folder/report1/report1/*    |   tr -s " "    |    cut -d' ' -f6-8    |     grep "^[0-9]"    |    awk 'BEGIN{ MIN=1440; LAST=60*MIN; "date +%s" | getline NOW } { cmd="date -d'\''"$1" "$2"'\'' +%s"; cmd | getline WHEN; DIFF=NOW-WHEN; if(NOW > DIFF){ print "Migrating: "$3; system("datalake/hadoop/bin/hadoop fs -copyToLocal /path/to/local_dir/"$3) }}'

하지만이 사람은 내가 몇 일보다 오래된 파일을 복사하고는 (이 경우 보고서 1에서) 하나의 디렉토리에서만 파일을 복사합니다.

이보다 유연하고 정확한 만들 수있는 방법이 있습니까. 이되지 파이썬, 배쉬로 해석 될 수 있다면 그것은 좋은 것입니다. 어떤 제안은 환영 또는 유사한 문제 좋은 답변에 링크되어있다.

또한, 일부 루프에있을 필요는 없습니다. 나 각 보고서에 대한 분리 코드 줄을 사용하는 것은 괜찮습니다.

해결법

  1. ==============================

    1.나는 이것을 테스트 할 수 없습니다,하지만 당신은 출력을보고 단계로이 단계를 테스트 할 수 있습니다 :주의 :

    나는 이것을 테스트 할 수 없습니다,하지만 당신은 출력을보고 단계로이 단계를 테스트 할 수 있습니다 :주의 :

    일반적으로 나는 절대로 말할 LS의 출력을 구문 분석하지만, 찾을 수 동등한이 없기 때문에 하둡, 당신은 여기에 선택의 여지가 없어 것입니다. (2.7.0 때문에, 문서에 따라 거기에 발견하지만, 그것은 매우 제한된다)

    1 단계 : 재귀 LS

    $ hadoop fs -ls -R /path/to/folder/
    

    2 단계 : 파일 만 CSV 파일을 선택하는 AWK를 사용하는 경우에만 디렉토리는 D로 시작하는 자신의 권한에 의해 인식되는, 그래서 우리는 사람들을 제외해야합니다. 그리고 CSV 파일은 "CSV"로 끝나는 마지막 필드로 인식됩니다

    $ hadoop fs -ls -R /path/to/folder/ | awk '!/^d/ && /\.csv$/'
    

    당신이 빈하거나 디렉토리 이름 여기에 재미 라인으로 끝낼하지 않도록 만들 ...

    3 단계 : 시간을 처리 할 AWK를 사용하여 계속합니다. 난 당신이 표준 AWK이 가정입니다, 그래서 GNU 확장을 사용하지 않습니다. 하둡를 출력 YYYY-MM-DD HH와 시간 형식 : mm. 이 형식은 정렬 할 수 있습니다 및 필드 6, 7에 위치하고 있습니다 :

    $ hadoop fs -ls -R /path/to/folder/  \
       | awk -v cutoff="$(date -d '-24 hours' '+%F %H:%M')" \
             '(!/^d/) && /\.csv$/ && (($6" "$7) > cutoff)'
    

    4 단계 : 파일 복사 하나씩 :

    먼저, 실행하고자하는 명령을 확인 :

    $ hadoop fs -ls -R /path/to/folder/  \
       | awk -v cutoff="$(date -d '-24 hours' '+%F %H:%M')" \
             '(!/^d/) && /\.csv$/ && (($6" "$7) > cutoff) {
                print "migrating", $NF
                cmd="hadoop fs -get "$NF" /path/to/local/"
                print cmd
                # system(cmd)
             }'
    

    (당신이 실행하려는 경우 # 제거)

    또는

    $ hadoop fs -ls -R /path/to/folder/  \
       | awk -v cutoff="$(date -d '-24 hours' '+%F %H:%M')" \
             '(!/^d/) && /\.csv$/ && (($6" "$7) > cutoff) {
                print $NF
             }' | xargs -I{} echo hadoop fs -get '{}' /path/to/local/
    

    (당신이 실행하려는 경우 에코 제거)

  2. ==============================

    2.당신은 예를 들어, "CP"와 함께 "찾기"를 사용하여 간단하게 할 수 있습니다 :

    당신은 예를 들어, "CP"와 함께 "찾기"를 사용하여 간단하게 할 수 있습니다 :

    find /path/to/directory/ -type f -name "*.csv" | xargs cp -t /path/to/copy
    

    24 시간보다 오래된 파일의 디렉토리를 청소하려면, 당신은 사용할 수 있습니다 :

    find /path/to/files/ -type f -name "*.csv" -mtime +1 | xargs rm -f
    

    어쩌면 당신은, 스크립트로 구현 크론의 작업으로 설정할 수 있습니다.

  3. from https://stackoverflow.com/questions/55364275/copy-files-to-local-from-multiple-directories-in-hdfs-for-last-24-hours by cc-by-sa and MIT license