最も古いファイルをあるディレクトリから別のディレクトリに移動するシェルスクリプト

最も古いファイルをあるディレクトリから別のディレクトリに移動するシェルスクリプト

私はシェルスクリプトに初めて触れました。私は解決策を探しています。ディレクトリにファイルが追加された場合に備えて、私のディレクトリに10個のファイルを保持する必要があります。最も古いファイルだけを別のディレクトリに移動したいと思います。私のディレクトリ名はWorkで、他のディレクトリ名はRegular_archieveと指定しました。私はこれを試しました。

work = /home/balaji/work
regular_archieve = /home/balaji/regular_archieve
cd $work
for i in 'ls -t | sed -e '1,10d' | xargs -d '\n' rm -f'
do
 mv $i $regular_archieve
done
if [ls -t | wc -1 > 10 | mv /home/balaji/regular-archieve]
 then
   echo "more than 10 n files"
fi
mv $(ls -t /home/balaji/work | sed -e '1,10d' | tail - 1) /home/balaji/regular_archieve

ただし、ファイルを別のディレクトリに移動することはできません。

このエラーが発生します。

mv: cannot stat 'file' : No such file or directory

ベストアンサー1

lsターミナルで見るもの以外の用途での出力を使うのは良いことではありません。バラよりなぜいいえ解析ls(および実行方法)?。代わりに、以下を使用してくださいfind

find /home/balaji/work/ -type f -printf '%C@\t%p\0' |
  sort -z -k1,1 -r -n |
  cut -z -f2 |
  head -z -n 10 | 
  xargs -0r echo mv -t /home/balaji/regular_archive/

findこれには、GNUバージョンの、、、およびsort(または少なくともNULレコード区切り文字オ​​プションをサポートする他のバージョン)cutが必要です。tailxargs-z

  • findすべての一般ファイルに対して-printf '%C@\t%p\0'最後に変更されたタイムスタンプ(%C@1970-01-01 00:00:00以降の秒数)とファイル名()を一覧表示するために使用されます。フィールドは単一のタブ文字()で区切られ、各レコードは%pNUL文字()で\t区切られます。\0
  • findの出力は、-r最初のフィールド()に対してのみファイルを数値逆順()でソートするためにsortにパイプされます。つまり、タイムスタンプに基づいています。-n-k 1,1
  • ソートの出力は、タイムスタンプフィールドを削除するためにパイプに接続されます(ソートが完了した後はもう必要ありません)。
  • カットの出力は、head最初の10項目を得るためにパイプに接続されます。
  • 最後に、head の出力がxargsrunmvコマンドにパイプされます。これはmvのGNU-t拡張子を使用するため、ファイル名の前にターゲットディレクトリを指定できます。

実際、これはrunとecho mvいうよりはrunmvなので、pre-runです。echoそれがあなたが望むことをすることを確信したら、それを取除きなさい。

注:これは以下に適用されます。どの含まれている可能性がある奇妙で迷惑な文字(スペース、改行、シェルメタ文字など)に関係なく、ファイル名。また、このfileコマンドには、検索基準を絞り込むために使用できる他の多くのオプションがあります。


以前のバージョンのGNU coreutils(<バージョン8.25など)を使用している場合cutでも、オプションはありませんhead。代わりにこれを使用できます。例えばtail-zawk

find /home/balaji/work/ -type f -printf '%C@\t%p\0' |
  sort -z -k1,1 -r -n |
  awk -F '\t' 'BEGIN {RS=ORS="\0"}; NR<=10 { $1=""; $0=$0; $1=$1 ; print }' |
  xargs -0r echo mv -t /home/balaji/regular_archive/

perlまたは、次のものを代わりに使用できますawk

 perl -F'\t' -0lane 'if ($. <= 10) {delete $F[0]; print @F}'

おすすめ記事