최신 5개 파일에 대한 스크립트를 유지하고 나머지 파일은 다른 대상으로 이동됩니다.

최신 5개 파일에 대한 스크립트를 유지하고 나머지 파일은 다른 대상으로 이동됩니다.

소스 코드 경로:

/var/log/

여기에는 4개의 폴더가 있습니다.ad1nrld,ad2nrld,icp1rmnrl,icp2rmnrl

모든 파일을 이라는 다른 대상으로 이동할 수 있습니다 /home/spsy/logs_bkp. 하지만 이 경로의 각 폴더(ad1nrld, ad2nrld, icp1rmnrl, icp2rmnrl)에 최신 5개 파일을 보관하고 /var/log나머지 파일은 /home/spsy/logs_bkp해당 경로로 이동하려고 합니다.

소스 경로에서 /var/log/ad1nrld- 최근 5개 파일만 표시되고 나머지는 /home/spsy/logs_bkp/ad1nrld해당 경로 로 이동됩니다.

다음 코드를 사용하여 파일을 이동해 보았더니 성공적으로 이동되었습니다. 하지만 최신 파일 5개를 해당 폴더에 보관할 수는 없습니다.

for i in `ls -1rt | egrep 'nrld|mnrl'`
do
cd $i
mv *log /home/spsy/logs_bkp/$i
echo "files moved for &i"
cd ..
done

최신 5개 파일을 유지하는 코드를 추가하면 다음 부분이 작동하지 않습니다.

for i in `ls -1rt | egrep 'nrld|mnrl'`
do
cd $i
count_files=`ls -lrt | wc -l`
if [ $count_files -gt 5 ];
then
tomove=$(($count_files-5))
for part in `ls -1rt`
do
if [ $tomove -gt 0 ]
then
mv $part /home/spsy/logs_bkp/$i
tomove=$(($tomove-1))
echo "files moved for &i"
cd ..
fi
done
fi
done

답변1

zsh일반적으로 Solaris에서 사용할 수 있는 간단한 버전을 설치하지 않는 한 다음을 수행할 수 있습니다.

#! /usr/bin/zsh -
src=/var/log dst=/home/spsy/logs_bkp
dirs=(ad1nrld ad2nrld icp1rmnrl icp2rmnrl)

ret=0
for dir ($dirs) () {
  if (( $# > 5 )) mv -- $@[6,-1] $dst/$dir/ || ret=$?
} $src/$dir/*(N.om)
exit $ret

omglob 확장 을 위해 glob 한정자를 사용합니다 o(만정기적인한정자 .) m​​수정 시간별(가장 어린 것부터 가장 오래된 것까지 ls -t). D숨겨진 파일도 고려하려면 한정자를 추가하세요.

glob 확장자는 디렉터리에 5개 이상의 파일이 있는 경우 6번째 파일을 마지막 파일로 이동하고 for이를 .$dir$dirs

ksh 또는 기타 쉘을 사용하면 glob 한정자가 없으면 수정 시간을 기준으로 파일 목록을 정렬하고 일반 파일로 제한하는 것이 어려운 부분입니다.

ls -t수정 시간을 기준으로 정렬하지만 파일 이름에 개행 문자가 포함되지 않는다는 것을 보장할 수 없으면 출력에서 ​​파일 목록을 쉽게 재구성할 수 없습니다. 그러한 특별한 상황이 발생하면 다음과 같이 할 수 있습니다.

#! /bin/sh -
src=/var/log dst=/home/spsy/logs_bkp
dirs='ad1nrld
ad2nrld
icp1rmnrl
icp2rmnrl'

IFS='
' # split on newline only
set -o noglob # disable globbing so we can use split+glob to split.

ret=0
for dir in $dirs; do # split+glob to split $dirs
  set --
  for file in $(ls -t -- "$src/$dir/"); do # split+glob to split ls output
    [ -f "$file" ] && [ ! -L "$file" ] && set -- "$@" "$src/$dir/$file"
  done
  if [ "$#" -gt 5 ]; then
    shift 5
    mv -- "$@" "$dst/$dir/" || ret="$?"
  fi
done
exit "$ret"

답변2

구문 분석에 의존하지 않고 및 줄 종결자로 ls사용하는 버전:find\0

(귀하가 Solaris를 사용하고 있고 GNU확장 기능을 사용하고 있으므로 이것이 귀하에게는 불가능할 수도 있지만 다른 사람들에게는 유용할 수 있습니다.)

dirs=(ad1nrld ad2nrld icp1rmnrl icp2rmnrl)
for dir in "${dirs[@]}"; do
    find "$dir" -maxdepth 1 -type f -printf '%T@\t%p\0' \
      | sort -rnz \
      | tail -z -n+6 \
      | cut -z -f2- \
      | xargs -r0 mv --backup=numbered -t logs_bkp/
done

답변3

스크립트가 실행 중입니다. ad1nrld,ad2nrld,icp1rmnrl,icp2rmnrl/var/log 경로에 4개의 폴더가 있습니다 . 스크립트는 해당 폴더에 최신 5개의 파일을 보관하고 나머지 파일은 경로의 해당 폴더로 이동됩니다 /home/spsy/logs_bkp.

코드는 다음과 같습니다.

cd /var/log
for i in `ls -1rt | egrep 'nrld|mnrl'`
do
cd $i
count_files=`ls -lrt | wc -l`
if [ $count_files -gt 6 ];
then
tomove=$(($count_files-6))
for part in `ls -1rt`
do
if [ $tomove -gt 0 ]
then
mv $part /home/spsy/logs_bkp/$i
tomove=$(($tomove-1))
fi
done
cd ..
fi
done

관련 정보