删除多个目录中除最大文件之外的所有文件

删除多个目录中除最大文件之外的所有文件

我有多个子目录,/home/usr/ProjZ/programs/每个子目录都包含多个(或一个).js文件。

我需要做的是.js,如果子目录包含多个文件,则删除除最大文件之外的所有文件;如果子目录仅包含一个.js文件,则不执行任何操作。

我该怎么做呢?

答案1

zsh

for dir (/home/usr/ProjZ/programs/*(/)) rm -f $dir/*.js(.NOL[2,-1])

请注意,如果有多个最大文件,则仅保留一个。哪一个取决于它们在当前目录中出现的顺序(通常或多或少是随机的)。

GNUly(最近的 GNU sedfor -z),等效项如下所示:

for dir in /home/usr/ProjZ/programs/*; do
  [ -d "$dir" && ! -L "$dir" ] || continue
  find "$dir" -type f -printf '%s:%p\0' | sort -rzn |
    sed -z '1d;s/[^:]*://' | xargs -r0 rm -f
done

答案2

我不清楚 .js 文件是否都在一个目录中,或者它们是否存在于该点下方的任何位置。

如果您只想从单个目录中删除除最大的 .js 之外的所有文件,您可以执行以下操作:

$ ls -S *.js | tail --lines=+2 | xargs rm

如果文件包含空格等奇怪字符,则这是不安全的。

如果 .js 可以存在于任何深度,我可能会编写脚本。

珀尔

use File::Find;
find(\&wanted, "/path/to/look/in");
my $biggest_file;
my $biggest_size = 0;
sub wanted {
  if ($_ =~ /\.js$/) {
    my ($size) = (stat $_)[7];
    if ($size > $biggest_size) {
      unlink $biggest_file if defined $biggest_file;
      $biggest_size = $size;
      $biggest_file = $File::Find::name;
    }
  }
}

答案3

当 .js 文件名称中可能包含空格,以及目录可能同时包含 .js 文件和其他扩展名时,这个小 bash 脚本将正确处理。

#!/bin/bash
查找 /home/usr/ProjZ/programs/* -type d |当读“x”时;做
NUMFILES=`ls -1 "$x"/*.js |厕所-l`
[[ $NUMFILES -gt 2 ]] && ls -1Sr "$x"/*.js 2>/dev/null |头 -n $(($NUMFILES-2)) | xargs -I{} rm -f "{}"
完成 2>/dev/null

答案4

一些很好的答案,但我宁愿保持简单并在bash.特别是如果你是新手。

以下是我将如何做的一些评论,以帮助您遵循:

#!/bin/bash

# Loop through all subdirectories
for dir in $(find /home/usr/ProjZ/programs/ -type d)
do

    # Get all .js files in this subdir
    files=$(find $dir -maxdepth 1 -type f -name '*.js')

    # If there's no files in here, just skip this subdir
    if [ -z "$files" ]
    then
        continue
    fi

    # Get deletion candidates (sort by size, remove the biggest, get filenames)
    rm_candidates=$(stat -c "%s %n" ${files} | sort -n | head -n -1 | cut -d" " -f2-)

    # Finally, remove each file
    for file in $rm_candidates
    do
        rm -f $file
    done
done

相关内容