保留最新 5 个文件的脚本,其余文件将移至其他目的地

保留最新 5 个文件的脚本,其余文件将移至其他目的地

源码路径:

/var/log/

这里我有 4 个文件夹,名为ad1nrld,ad2nrld,icp1rmnrl,icp2rmnrl

我可以将所有文件移动到名为 的其他目的地/home/spsy/logs_bkp。但我想保留此/var/log路径的每个文件夹(ad1nrld、ad2nrld、icp1rmnrl、icp2rmnrl)中的最新5个文件,其余文件将移至/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 限定符来o进行 glob 扩展(仅常规的带有限定符的文件.)按m修改时间(从最年轻到最老ls -t)。D如果您还想考虑隐藏文件,请添加限定符。

该 glob 扩展被传递给一个匿名函数,只要目录中存在超过 5 个文件,该函数就会将第 6 个文件移动到最后一个文件,并for在.$dir$dirs

对于 ksh 或其他 shell,如果没有 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,而是使用findand\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

脚本正在运行。我有 4 个ad1nrld,ad2nrld,icp1rmnrl,icp2rmnrl在 /var/log 路径中​​命名的文件夹。脚本会将最新的 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

相关内容