폴더에 최신 파일만 보관하고 오래된 파일을 보관 위치로 이동하는 방법

폴더에 최신 파일만 보관하고 오래된 파일을 보관 위치로 이동하는 방법

내 폴더에는 다음과 같은 파일이 여러 개 있습니다.

ContractAdjustments.CHRS201804202144.txt
ContractAdjustments.CHRS201804212144.txt
ContractAdjustments.CHRS201804222144.txt
ContractAdjustments.CHRS201804232144.txt

최신 파일만 보관하고 나머지는 아카이브 위치로 이동하고 싶습니다. 다음 스크립트를 사용하고 있는데 오류가 발생합니다.

$ find -maxdepth 1 -type f -iname 'ContractAdjustments.*.TXT' -printf '%T@|%p\n' | sort -r -n | tail -n +2 | cut -d'|' -f2 | xargs -i mv {} ARCHV

답변1

#!/bin/sh

mkdir -p ARCHIVE || exit 1

newest=
for file in ContractAdjustments.*.txt; do
    if [ -f "$file" ]; then
        if [ -z "$newest" ]; then
            # this is the first file, initialize "newest"
            newest=$file
        elif [ "$file" -nt "$newest" ]; then
            # file is newer than "newest",
            # archive "newest" and set new newest file
            mv -i "$newest" ARCHIVE
            newest="$file"
        else
            # file is older, archive it
            mv -i "$file" ARCHIVE
        fi
    fi
done

if [ -n "$newest" ]; then
    printf 'Done. Newest file = %s\n' "$newest"
else
    echo 'No files found'
fi

테스트가 내장 명령으로 구현되면 /bin/sh스크립트는 최신 파일을 변경하지 않은 채 모든 이전 파일을 폴더로 이동합니다.-nt[ARCHIVE

이는 주어진 패턴과 일치하는 파일 이름을 반복하고 각 파일에 대해 지금까지 발견된 최신 파일에 대해 타임스탬프를 테스트하고 최신 파일인지 오래된 파일인지에 따라 파일을 이동하는 방식으로 수행됩니다.

스크립트는 파일 이름에 공백 문자 등을 유지하는 작업을 올바르게 처리합니다. 이 특별한 경우에는 문제가 되지 않을 수 있지만 일반적으로 Unix 파일 이름에는 파일 이름 와일드카드뿐만 아니라 공백과 삽입된 줄 바꿈이 포함될 수 있습니다.


들르고 싶다면파일 이름파일의 타임스탬프를 기준으로 정렬하는 대신 다음을 수행하세요.

#!/bin/sh

mkdir -p ARCHIVE || exit 1

set -- ContractAdjustments.*.txt

while [ "$#" -gt 1 ]; do
    mv -i "$1" ARCHIVE
    shift
done

printf 'Done. Newest file = %s\n' "$1"

이는 위치 인수( 등)를 주어진 패턴과 일치하는 파일 목록 $1으로 설정합니다. $2그런 다음 목록에 여전히 여러 개의 파일이 있으면 목록의 첫 번째 파일을 디렉터리로 이동 ARCHIVE하고 목록에서 제거합니다. 목록의 마지막 파일은 파일 이름을 기준으로 마지막 순위가 매겨진 파일입니다(해당 파일은 현재 위치에 유지됩니다).

답변2

간단한 방법은 다음과 같습니다.

mv `ls -t ContractAdjustments.*.txt | awk '{ iteration+=1; if (iteration > 1) { print } } ' ` ARCHV

물론 이는 가장자리 조건(예: 디렉터리에 파일이 하나만 있는 경우)에서 오류를 생성하지만 항상 작동합니다.

답변3

첫 번째 파일을 제외한 각 파일의 목록을 변수에 넣고 해당 파일에 대해 for 루프를 실행합니다.

 listinmemory=`ls -alht | tail -n +5 | awk '{print $9}'`; for each in $listinmemory; do mv $each /path/to/directory; done

ls -alht아무것도 실행하고 싶지 않은 4줄이 나열됩니다.

total 123K
drwxr-xr-x.  5 user user 1.0K Jun 27 09:20 .
drwx------. 13 user user 2.0K Jun 27 10:36 ..
-rw-rw-r--.  1 user user 3.0K Jun  6 18:29 file1 

가장 최근 파일과 3줄 - 그 다음에는 실행한 모든 파일이므로 tail -n +5처음 4줄을 건너뛰고 mv $each /path/to/directory찾은 모든 파일을 실행합니다!

답변4

ls귀하의 경우 cd디렉토리로 구문 분석하고 다음을 수행하는 것은 좋은 생각이 아닙니다.

 for CA in $(find . -maxdepth 1 -type f -name ContractAdjustments\*.txt | head --lines=-1); do mv $CA /path/to/archive/; done

명령 대체가 포함된 루프를 사용하여 for디렉터리에서 지정한 형식으로 시작하는 모든 파일을 찾아 ContractAdjustments*.txt두 번째 옥텟의 날짜를 기준으로 가장 오래된 것부터 최신 것 순으로 나열합니다. 그런 다음 파이프를 통해 --head --lines=-1마지막 줄(최신 파일)을 제외한 모든 항목을 인쇄하고 해당 값을 변수 CA(ContractAdjustments의 경우)에 전달합니다. 마지막으로 최신 파일을 제외한 모든 파일을 아카이브 위치로 이동하는 do데 사용됩니다 .mv

관련 정보