Bash

如何將 n 個最新文件複製到特定目錄?

  • September 4, 2021

使用

find $dirname -printf "%T@ %Tc %p\n" | sort -n | tail -n 15

我可以在下面的目錄結構中找到 n(在我的範例中為 n = 15)最新文件$dirname。現在我想將文件複製(或連結)到一個目錄$current中(我想定期將其作為後台腳本執行,以查看所有新添加的文件。

這樣做的背景是,我將一個目錄結構(通過rclone)從 ms sharepoint 鏡像到我的筆記型電腦,然後我想要一個目錄$current顯示所有 n 個最新修改的文​​件。

嘗試類似下面的 bash 腳本,執行從cron

#!/bin/bash

# exit on any error
set -e
set -o pipefail

# defaults for the options 
n=15
dirname='/default/path/to/your/files'
current='/default/path/to/the/current/dir'

while getopts ':n:d:c:' opt ; do
 case "$opt" in
   n) n="$OPTARG";;
   d) dirname="$OPTARG";;
   c) current="$OPTARG";;
   :) echo "Error: '-$OPTARG' requires an argument" >&2 ; exit 1 ;;
   *) echo "Error: unknown option '-$OPTARG'" >&2 ; exit 1 ;;
 esac
done

if [ ! -d "$current" ] ; then
 if ! mkdir -p "$current" ; then
   echo "Error: '$current' can't be created or already exists and isn't a directory" >&2
   exit 1
 fi
fi

rm -f "$current"/*
# alternatively, to delete only symlinks in $current:
# find -H "$current/" -maxdepth 1 -type l -delete

find "$dirname/" -type f -printf "%T@\t%p\0" | 
 sort -z -r -n |
 head -z -n "$n" |
 sed -z -e 's/^[^\t]*\t//' |
 xargs -0r readlink -e -z |
 xargs -0r ln -s -t "$current/"

這使用 NUL 作為文件名之間的分隔符,因此它將與包含任何有效字元的文件名一起使用(NUL 是路徑/文件名中唯一無效的字元)。

管道中的sed腳本會刪除時間戳欄位(直到並包括第一個 TAB 字元的所有內容**-**都是必需的,因為 TAB 是文件名中的有效字元)。而不是sed, 你可以cut -z -f2-在這裡使用。

我使用了sort -r -nandhead -n而不是tail -n因為它會稍微快一點 -head只要它輸出前 15 個文件名就可以退出,同時tail必須讀取整個輸入。

xargs -0r使用了兩次。首先用於readlink獲取每個文件名的完整規範路徑,然後$current使用ln.

注意:這需要find支持的printf版本sorthead以及支持NUL 分隔的輸入/輸出的版本,readlink以及支持目標目錄選項的版本,以及支持的版本。例如所有這些的 GNU 版本。sed``-z``ln``-t``xargs``-0

另外,我不記得\tfor tab 在其他版本的 sed 中是否可以在括號表達式中使用,但它確實可以在 GNU sed 中使用。

如果您正在執行 Linux,那麼您將擁有 GNU 版本的 coreutils、findutils、sed 等(除非您做了一些非常奇怪和莫名其妙的瘋狂的事情,比如安裝非 GNU 版本)。

引用自:https://unix.stackexchange.com/questions/667581