次のように、ファイル名が数値に変更され続けるディレクトリがあります。
-rw-rw----. 1 root root 10493952 May 7 10:39 A0000000.LOG
-rw-rw----. 1 root root 10493952 May 7 08:38 A0000001.LOG
-rw-rw----. 1 root root 10493952 May 7 08:38 A0000002.LOG
...
...
-rw-rw----. 1 root root 10493952 May 7 08:38 A0000582.LOG
...
and so on...
いつでも私のアプリケーションはリストされたファイルからファイル名を削除します。捨てなければならないそれファイルおよび次より大きい値を持つその他のファイルそれファイルをリモートホストに再同期する
アプリケーションがファイルを投げたとしますA0000096.LOG
。私 A0000097.LOG
も創造されるのを見るなら::
rsync A* --exclude A0000096.LOG --exclude A0000097.LOG user@remoteHost:/somedir/
指示:
アプリケーションは、毎時間実行されるrsync cronジョブに異なるファイル名を生成します。この例では、ファイル名は次のようになります。
A0000096.LOG
A0000096.LOG
アプリケーション出力ファイル名(上記の例では)よりも高い値のファイルは、アプリケーション出力ファイル名と同じ生成日時スタンプを持つことができます。rsyncが起動すると、アプリケーションの出力ファイル名は、より高い値を持つファイルよりも最新の日付/タイムスタンプを持つことができます。
より高い値のファイルが生成されない場合、または1つ以上のファイルが生成される可能性があります(おそらく10〜20個)
質問:この制限により、すべての親数値ファイルをrsync bashスクリプトに供給して除外する方法がわかりません。
助けてくれてありがとう。
答え1
質問を正しく理解したら、A0000000
.rsyncの範囲内のすべてのファイルを介してrsyncをしたいと思いますA0000095
。A*
除外するファイル名を識別するのではなく、目的のファイル名を生成するために肯定的なワイルドカードリスト(globまたはファイル名拡張パターンとも呼ばれる)を使用するとは言わないでください。これは、範囲をサブ範囲に分割することによって達成されます。
Subrange Wildcard
A0000000-A0000089 A00000[0-8][0-9]
A0000090-A0000095 A000009[0-5]
だからあなたは言うでしょう
rsync A00000[0-8][0-9] A000009[0-5] user@remoteHost:/somedir/
1つの例でこのアプローチを一般化できない場合は、97169を検討してください。
Subrange Wildcard
A0000000-A0089999 A00[0-8][0-9][0-9][0-9][0-9]
A0090000-A0096999 A009[0-6][0-9][0-9][0-9]
A0097000-A0097099 A00970[0-9][0-9]
A0097100-A0097159 A00971[0-5][0-9]
A0097160-A0097168 A009716[0-8]
想像できるように、これらのワイルドカードの一部は既存のファイルと一致しません。この場合、
shopt -s nullglob
rsync
コマンドを実行し続け、失敗したワイルドカードを無視するようにシェルに指示します(たとえば、nullに拡張)。
答え2
数値は同じ幅でゼロで埋められるため、数値の順序は辞書式の順序と同じです。したがって、あなたの質問は、語彙順に特定のファイルで始まるファイルを削除することです。
改行で区切られたファイル名を含む文字列を作成し、文字列置換を使用して文字列の終わりを削除し、引用符なしの拡張機能を使用して切り捨てられた文字列をリストに戻すことでこれを行うことができます。ファイル名に改行文字がなく、シェルがbashまたはkshであるとします(通常のshの場合は、名前付き配列の代わりに位置引数を使用する必要があります)。
nl=$'\n' # newline, we use it as a separator
cut_from=A0000096.LOG
log_files=(A???????.LOG)
set -f; IFS="$nl" # disable wildcard expansion and set the word separator to newline only
log_files="$nl${log_files[*]}$nl" # turn the array into a string with newlines separating elements
log_files=(${log_files%"$nl$cut_from$nl"}) # remove elements from $cut_from onwards and split the string into an array
unset IFS; set +f
rsnyc -a "${log_files[@]}" … elsewhere:/some/dir
答え3
私の質問に答えるには:
方法1
CUT_LOG=A0000096.LOG #Assuming app throws a file - A0000096.LOG and I've to exclude this and any other files having higher numerical value than this file: A0000096.LOG. e.g. A0000097.LOG etc.
LISTLOG=`ls -1 /Source_Dir/A*.LOG | sed "/$CUT_LOG/,$ d"` # Instantiate a variable - LISTLOG, that will hold files list excluding A0000096.LOG and any other files having higher numerical value than this A0000096.LOG
rsync -a `echo "${LISTLOG[@]}"` user@remoteHost:/somedir/ # Transfers the files excluding A0000096.LOG and excluding any other files with higher numerical values than A0000096.LOG
方法2【ループの使用(推奨しない)
for line in `echo "${LISTLOG[@]}"`; do # Recursively loop through the array and rsync each entry
rsync -a $line user@remoteHost:/somedir/
done
答え4
接線閉鎖ザイルズの観察ファイル名は語彙順にソートされます。これを使用して、zsh
rsync用のフィルタファイルを作成できます。
cut_log=A0000096.LOG zsh -c 'logfilter() { ! [[ "$REPLY" < "$cut_log" ]] }; print -l A*.LOG(+logfilter)' > .exclude_file
rsync A* --exclude-from=.exclude_file user@remoteHost:/somedir/
rm .exclude_file
もちろん、これらすべてをzshで基本的に実行できますが、便利なzsh機能を使用してbashスクリプトを拡張する方法を紹介します。この関数は「グローバル予選」eString
とセクションで説明されています+cmd
。A*.LOG
各候補を与えられた関数に渡してフィルタリングを拡張する必要があります。関数の引数名はそのため、結果リストに含めるか除外するかを決定するために、値を語彙的REPLY
に比較します。$cut_log
rsync
上記のコードは、ログファイルを見つけて検索するためにログファイルを含むディレクトリで実行されていると仮定していますzsh
。
.exclude_file
これにより、コマンドを実行する前に確認して練習を簡単に実行できますrsync
。
ファイルが多すぎると思われる場合含むコマンドラインで(引数が多すぎるとコマンドが失敗するように)、引数が足りない場合入らないようにするファイルの場合は、論理を反転してファイルrsync
に指示し、論理を切り替えて反転()を削除できます。--include-from
logfilter
!