複数のディレクトリから最大のファイルを除くすべてを削除

複数のディレクトリから最大のファイルを除くすべてを削除

複数のサブディレクトリがあり、/home/usr/ProjZ/programs/各ディレクトリには複数(または1つ).jsのファイルが含まれています。

私がしなければならないのは、.jsサブディレクトリに複数のファイルが含まれている場合は最大ファイルを除くすべてのファイルを削除し、サブ.jsディレクトリにファイルが1つしか含まれていない場合は何もしません。

どうすればいいですか?

答え1

そしてzsh

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

最大のファイルが複数ある場合は、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ファイルがすべて1つのディレクトリにあるのか、それともそのポイントの下にあるのかはわかりません。

単一のディレクトリから最大の.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

この小さなbashスクリプトは、.jsファイル名にスペースを含めることができ、ディレクトリに.jsファイルと他の拡張子の両方を含めることができる場合は正しく処理します。

#!/bin/bash
"x"を読むとき/home/usr/ProjZ/programs/* -type d |
NUMFILES=`ls -1 "$x"/*.js |トイレ-l`
[[ $NUMFILES -gt 2 ]] && ls -1Sr "$x"/*.js 2>/dev/null |head-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

関連情報