여러 디렉터리에 있는 여러 파일의 최신 버전 찾기

여러 디렉터리에 있는 여러 파일의 최신 버전 찾기

저는 애플리케이션을 작성 중이며 전제 조건 중 하나는 여러 디렉터리를 조사하고 각 파일의 최신 버전을 찾을 수 있어야 한다는 것입니다.

최신 파일을 성공적으로 사용 ls하고 가져왔지만 동일한 파일이 여러 디렉터리에 있는 경우 각 파일의 최신 버전이 아닙니다. find한 가지 주목할 점은 파일 이름을 반드시 알 수는 없지만 디렉터리 이름은 알 수 있다는 것입니다.

예:DIR1, DIR2 및 DIR3에는 각각 FileA 및 FileB 버전이 포함되어 있습니다. 세 개 이상의 디렉터리에 모두 포함된 최신 버전의 FileA 및 FileB가 필요합니다.

누구든지 아이디어가 있나요?

답변1

올바른 도구를 선택하셨습니다.

  • ls -t파일을 시간별로 정렬하여 최신 파일을 선택할 수 있는 좋은 방법입니다.
  • find디렉터리 및 하위 디렉터리에서 특정 패턴과 일치하는 파일을 찾는 데 적합한 도구입니다.

물론 까다로운 부분은 파일 이름별로 일종의 그룹화가 필요하고 각 그룹에서 최신 파일을 선택해야 한다는 것입니다. 이러한 요구 사항으로 인해 최신 버전을 찾기 위해 각 대상 파일 이름을 반복하는 루프가 필요하다고 생각합니다.

파일이 또는 에 있다고 가정하면 $dir1다음 $dir2$dir3같이 일부 스키마의 최신 버전을 찾는 함수를 작성할 수 있습니다.

find_latest() {
    pattern=$1
    ls -t "$dir1/$pattern" "$dir2/$pattern" "$dir3/$pattern" | head -n 1
}

그런 다음 패턴 이 있다고 가정하면 access.log다음 과 같이 반복할 수 있습니다.error.logx*

for pattern in access.log error.log 'x*'; do
    latest=$(find_latest 'a*')
    echo $latest
done

위의 가정이 유지되지 않고 파일이 $dir1, 또는 $dir2의 하위 디렉터리에 있을 수 있는 경우 를 $dir3사용해야 하면 find조금 더 복잡해집니다.

find_latest() {
    pattern=$1
    find "$dir1" "$dir2" "$dir3" -name "$pattern" -print0 | xargs -0 ls -t | head -n 1
}

작은 주의 사항이 있습니다. 이 head -n 1단계에서는 경로에서 개행 문자 뒤의 부분이 잘리기 때문에 경로에 개행 문자가 포함되어 있으면 이 함수가 제대로 작동하지 않습니다. 그런 길이 없기를 기도합니다 ;-)

답변2

다음과 같은 방법으로 이 작업을 수행할 수 있습니다 pax.

pax -wrtvZs"|.*/||p" ./DIR[123] "$PWD"

그래서 나는 그것을 논쟁으로 분해하려고 노력할 것입니다:

  • -wr- write와 read는 함께 pax파일을 보관하기보다는 복사해야 함을 의미합니다. 복사본을 버리고 -l.

  • -tpax- 메타데이터를 확인하기 위해 파일을 읽기 전의 상태로 모든 파일 액세스 시간을 재설정합니다.

  • -v- 작업 시간이 깁니다.

  • -Z- 소스 파일의 수정 시간은 가능한 모든 이름 교체가 완료될 때까지 비교되지 않습니다.

    • 그것은 이것입니다(그리고 다음에 나올 내용)이렇게 하면 모든 것이 매우 쉬워집니다. 이것이 없으면 - 그리고 아마도 다른 곳에서 직면하게 될 문제는 - 기본 이름을 공유하더라도 DIR1/FILEA다른 파일입니다. DIR2/FILEA그러니까 이게 없으면 절대 비교가 안 되겠죠...
  • -s- 파일 이름의 일부를 표준 정규식으로 바꿉니다 sed.

    • 여기서는 각 파일의 모든 부분을 기본 이름으로 줄였습니다 -Z.모두 FILEAs로 변경하고 최신 내용만 "$PWD".

나는 이 모든 것을 확인하기 위해 다음 테스트를 사용합니다.

for d in DIR3 DIR1 DIR2
do  cd ~; mkdir -p "$d"; cd "$d"
    sleep 90; touch FILEB FILEA
done; cd ~

...테스트 세트를 가져옵니다. 최종 수정 시간은 다음과 같습니다.

ls -l ./DIR[123]/FILE[AB]                                
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:28 ./DIR1/FILEA
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:28 ./DIR1/FILEB
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:29 ./DIR2/FILEA
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:29 ./DIR2/FILEB
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:26 ./DIR3/FILEA
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:26 ./DIR3/FILEB

그래서 내가 실행할 때 :

pax -wrtvZs"|.*/||p" ./DIR[123] "$PWD"
ls -l ./FILE[AB]

...출력은...

./DIR1/FILEA >> FILEA
/home/mikeserv/FILEA
./DIR1/FILEB >> FILEB
/home/mikeserv/FILEB
./DIR2/FILEA >> FILEA
/home/mikeserv/FILEA
./DIR2/FILEB >> FILEB
/home/mikeserv/FILEB
./DIR3/FILEA >> FILEA
./DIR3/FILEB >> FILEB

-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:29 ./FILEA
-rw-r--r-- 1 mikeserv mikeserv 0 Dec 20 03:29 ./FILEB

당신은 그것이 일어나는 것을 볼 수 있습니다. -s|||p파일 이름이 변경 되면 p수정자는 로 변경됩니다 stderr. 따라서 DIR1파일이 먼저 평가되어 에 복사된 $PWD다음 DIR2파일이 동일한 처리를 받지만 DIR3파일은 $PWD/FILE[AB]현재보다 최신이므로 복사되지 않습니다.

관련 정보