Bashの変換の問題

Bashの変換の問題

検索にラッパーを試しましたが、次の問題が発生しました。たとえば、一部のディレクトリをパラメータとして指定したいが、最後のパラメータは常にデータを削除する必要がある期間を示す数値です。たとえば、

rmoldfiles dir1 dir2 dir3 20

30日以上経過したファイルを削除する必要があります。looking at mtime of course

スクリプトは次のとおりです。

#!/bin/bash

die()
{
  echo >&2 "$@"
  exit 1
}

usage()
{
  echo >&2 "Usage: $0 [dir1 dir2 dir3] [days old]"
  die
}

if [[ (($# < 1)) || -f "$1" ]]; then
  if [[ -f "$1" ]]; then 
    printf '%s\n' "Please provide a directory"
  fi
  usage
fi 

while (( $# )); do 
  while IFS= read -r -d $'\0' file; do
    printf 'rm %s\n' "$file" 
    sleep 1
  done < <(find "$1" -type f -mtime +$2 -print0)
  shift
done

echo "Done deleting"

質問

ディレクトリはありますが、shift最後のパラメータではありません。

答え1

いくつかの解決策。

  1. 最後のコマンドライン引数を選択します。

    args=( "$@" )
    num=${args[-1]}
    args=( "${args[@]:0:${#args[@]} - 1}" )
    

    (その後、これらのファイルを削除するために使用されますfind "${args[@]}" -type f -mtime "+$num" -print -delete)。

  2. 番号を最初に入力してください。

     num=$1; shift
    

    (これはfind "$@" -type f -mtime "+$num" -print -deleteファイルを削除するために使用されます)。

ループは、処理するディレクトリが数百または数千個ある場合にのみ必要です。この場合、findコマンドを一度呼び出すのに時間が長すぎます。それ以外の場合は繰り返さないでください。find複数の検索パスを使用できます。

rm遅延を挿入し、それを明示的に使用し、各ファイルにフォーマットされた出力を持たせたい場合は、次のようにします。

find "$@" -type f -mtime "+$num" -exec sh -c '
    for pathname do
        printf "Removing %s\n" "$pathname"
        rm -- "$pathname"
        sleep 1
    done' sh {} +

お探しの場合するディレクトリを繰り返す必要があります(またはこれが良い場合)。

# Assumes that the arguments are in the order
#      num dir1 dir2 dir3 ...

num=$1
shift

for dir do
    printf 'Processing %s...\n' "$dir"

    find "$dir" -type f -mtime "+$num" -exec sh -c '
        for pathname do
            printf "Removing %s\n" "$pathname"
            rm -- "$pathname"
            sleep 1
        done' sh {} +
done

または、

# Assumes that the arguments are in the order
#      dir1 dir2 dir3 ... num

args=( "$@" )
num=${args[-1]}
args=( "${args[@]:0:${#args[@]} - 1}" )

for dir in "${args[@]}"; do

    # as above

done

答え2

age パラメーターの前には 3 つのディレクトリだけが期待され、提供されるので、無分別に繰り返さず、明示的に繰り返してください。

for dir in 1 2 3; do
  # work with "$1"
  shift
done

または、引数が 1 つ残ったときにループを停止します。

while [ "$#" -gt 1 ]; do
  echo "Work with $1"
  shift;
done

「days」パラメータは各交互に移動するため、最初に保存する必要があります。

days=$4

...ループを呼び出す前に。

...ディレクトリの数に関係なく転送を許可する場合:

[ "$#" -gt 1 ] || exit 1
days=${@: -1}
while [ "$#" -gt 1 ]; do
  echo work with "$1" and "$days"
  shift
done

これはbash配列を取得し、$@最後の要素(としてマークされ、-1修飾子として解釈されないようにスペースで区切られている:)を要求し、1つが残るまで(最後の最初の「日」)引数を1つずつ繰り返します。議論)。

答え3

(( $# ))次へ変更してください(( $# > 1))

while (( $# > 1 )); do
  echo "file is: $1"
done

echo "days are: $1"

関連情報