删除最旧的文件

d3v*_*il0 9 shell rm files

我试图从目录中删除旧文件,只留下 3 个最新文件。

cd /home/user1/test

while [ `ls -lAR | grep ^- | wc -l` < 3 ] ; do

    rm `ls -t1 /home/user/test | tail -1`
    echo " - - - "

done
Run Code Online (Sandbox Code Playgroud)

条件语句有问题。

l0b*_*0b0 9

如果你想遍历文件,千万不要使用ls*. tl;dr 在很多情况下,您最终会删除错误的文件,甚至是所有文件。

也就是说,不幸的是,在 Bash 中这是一件很棘手的事情。在我更老重复问题上 有一个有效的答案,您可以稍作修改即可使用:find_date_sorted

counter=0
while IFS= read -r -d '' -u 9
do
    let ++counter
    if [[ counter -gt 3 ]]
    then
        path="${REPLY#* }" # Remove the modification time
        echo -e "$path" # Test
        # rm -v -- "$path" # Uncomment when you're sure it works
    fi
done 9< <(find . -mindepth 1 -type f -printf '%TY-%Tm-%TdT%TH:%TM:%TS %p\0' | sort -rz) # Find and sort by date, newest first
Run Code Online (Sandbox Code Playgroud)

* 没有冒犯的家伙 - 我ls以前也用过。但确实不安全。

编辑:find_date_sorted的单元测试。

  • 如果我可以无情地从@Peter.O 那里窃取一个想法,请尝试使用 `((++counter&gt;3))` 作为您的测试。它非常简洁。至于oneliners:如果将代码包装在一个函数中是一个问题,那么不要担心它。 (2认同)

Gil*_*il' 5

到目前为止,最简单的方法是使用 zsh 及其glob 限定符Om按年龄递减排序(即最老的在前)并[1,3]仅保留前三个匹配项。

rm ./*(Om[1,3])
Run Code Online (Sandbox Code Playgroud)

有关更多示例,另请参阅如何在 zsh 中过滤 glob

并且请注意l0b0 的建议:如果您的文件名包含 shell 特殊字符,您的代码将被严重破坏。

  • @Ryan 那是给你的 zsh。 (2认同)

小智 5

要使用 zsh glob 删除除 3 个最新文件之外的所有文件,您可以使用Om(大写 O)将文件从最旧到最新排序,并使用下标来获取您想要的文件。

rm ./*(Om[1,-4])
#    | ||||  ` stop at the 4th to the last file (leaving out the 3 newest)
#    | |||` start with first file (oldest in this case)
#    | ||` subscript to pick one or a range of files
#    | |` look at modified time
#    | ` sort in descending order
#    ` start by looking at all files
Run Code Online (Sandbox Code Playgroud)

其他例子:

# delete oldest file (both do the same thing)
rm ./*(Om[1])
rm ./*(om[-1])

# delete oldest two files
rm ./*(Om[1,2])

# delete everything but the oldest file
rm ./*(om[1,-2])
Run Code Online (Sandbox Code Playgroud)


Arc*_*ege -1

首先,该-R选项用于递归,这可能不是您想要的 - 它也会在所有子目录中搜索。其次,<运算符(当不被视为重定向时)用于字符串比较。你可能想要-lt。尝试:

while [ `ls -1A | grep ^- | wc -l` -lt 3 ]
Run Code Online (Sandbox Code Playgroud)

但我会在这里使用 find :

while [ `find . -maxdepth 1 -type f -print | wc -l` -lt 3 ]
Run Code Online (Sandbox Code Playgroud)