내 폴더에는 다음과 같은 파일이 여러 개 있습니다.
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