비슷한 이름을 가진 파일 찾기, 가장 오래된 파일 삭제, 가장 최근 파일 이름 바꾸기

비슷한 이름을 가진 파일 찾기, 가장 오래된 파일 삭제, 가장 최근 파일 이름 바꾸기

서로 다른 하위 폴더에 비슷한 이름을 가진 파일이 많이 있지만 모두 패턴을 따르는 상황이 있습니다.

file1
file1 (Copy)
/folder1/file2.txt
/folder1/file2 (Copy).txt
/folder1/file3.png
/folder1/file3 (Copy).png

각 파일은 복사본과 동일한 폴더에 있고 확장명이 동일합니다. 차이점은 (Copy)이름 끝에 이름이 있다는 것입니다.

이러한 모든 파일을 가져오고 가장 오래된 파일을 삭제한 다음 이름을 바꿔야 하는 경우 결국 파일 이름을 에서 로 변경 file1 (Copy)( file1즉, 접미사 제거 )하고 싶습니다.(Copy)

find사용 하려고 했는데 mv가장 최근 항목을 이동하라고 어떻게 말해야 할지 모르겠습니다.

답변1

펼친find+bash솔루션(GNU 구현도 필요함 stat):

find . -type f -name "* (Copy).*" -exec bash -c 'p="${0%/*}"; bn="${0##*/}"; 
        main_bn="${bn/ (Copy)/}"; 
        if [ -f "$p/$main_bn" ]; then 
           t_copy_file=$(stat -c %Y "$0"); t_main_file=$(stat -c %Y "$p/$main_bn"); 
           if [[ $t_copy_file -gt $t_main_file ]]; then 
               mv "$0" "$p/$main_bn"; 
           else
               rm "$0"; 
           fi; 
        fi' {} \;

  • p="${0%/*}"- 기본 이름이 잘린 파일 경로/경로
  • bn="${0##*/}"- 파일의 기본 이름
  • main_bn="${bn/ (Copy)/}"- (Copy)기본 이름에서 하위 문자열을 제거하여메인/공통기본 이름
  • if [ -f "$p/$main_bn" ]- 만약에메인/원본파일이 존재합니다(심볼릭 링크 확인 후 일반 파일인 것으로 확인됨).
    • t_copy_file=$(stat -c %Y "$0")- 발견된 마지막 수정 시간을 가져옵니다."복사"파일
    • t_main_file=$(stat -c %Y "$p/$main_bn")- 마지막 수정 시간을 가져옵니다.원래의파일
    • if [[ $t_copy_file -gt $t_main_file ]]- 만약에"복사"파일이 최근 파일입니다. 해당 파일을 다음 위치로 이동하세요.원래의하나 (만들어봐원래의) 와 함께mv "$0" "$p/$main_bn"
    • 그렇지 않으면 -원래의파일이 최근 파일이므로 "를 제거했습니다.복사" 파일rm "$0"

-nt또는 파일 테스트 연산자를 사용하면 조금 더 짧습니다 ( [ new­er­file –nt olderfile ]- newerfile이보다 최근에 변경되었는지 확인 olderfile하거나 newerfile존재하고 olderfile존재하지 않는지 확인).

find . -type f -name "* (Copy).*" -exec bash -c 'p="${0%/*}"; bn="${0##*/}"; 
        main_bn="${bn/ (Copy)/}"; 
        if [ -f "$p/$main_bn" ]; then 
           if [ "$0" -nt "$p/$main_bn" ]; then 
               mv "$0" "$p/$main_bn"; 
           else
               rm "$0"; 
           fi; 
        fi' {} \;

답변2

다음을 사용하면 더 쉬울 수 있습니다 zsh.

setopt extendedglob # best in ~/.zshrc
for file (./**/?*" (Copy)"*(ND.)) {
  base=$file:h/${${file:t}/" (Copy)"}}
  [[ ! -f $base || -L $base ]] ||
    if [ $file -nt $base ]; then
      mv $file $base
    else
      rm -f $file
    fi
}

먼저 파일이 없는지 확인하는 것이 좋습니다 file (Copy) (Copy).txt.

  • **/: 모든 수준의 하위 디렉터리
  • N:널글로브오류가 발생하는 대신 일치하는 항목이 없으면 아무것도 확장하지 않음
  • D: 숨겨진 파일( D또는 파일)을 포함하고 숨겨진 디렉터리로 내려갑니다.
  • .:만 포함정기적인파일(디렉토리 없음, FIFO, 장치, 심볼릭 링크...)
  • $file:h:머리다음과 같이 파일(디렉토리 부분)의csh
  • $file:t:꼬리(파일명 부분)
  • ${var/pattern/replacement}, 여기에는 대체품이 없습니다.
  • [[ ! -f $base || -L $base ]] ||...안전 장치로서 비정규 파일이나 심볼릭 링크(일반 파일을 가리키는 경우에도)를 건너뜁니다.
  • [ $file -nt $base ]: $file마지막으로 수정된 경우 true를 반환합니다.~ 후에 $base(또는 $base액세스할 수 없으면 위의 확인에 따라 발생하지 않아야 합니다).

관련 정보