2016-06-27 15 views
0

foo.logとそのログの巡回兄弟foo.1.gzfoo.2.gzを最新のものから古いものへと繰り返したいと思っています。 foo.barPOSIX glob - 1つ以上の[〜:digit:]の一致方法

幸いにも、logrotateは、最新のものからアルファベットのものまでが同じ順序です。

私の元の試みはfor f in $(ls -t foo.*); do ...でしたが、shellcheckIterating over ls output is fragile. Use globs. [SC2045]となりました。プラスこのコードは、望ましくないfoo.barと一致します。

しかしどのように任意の桁数をグロブパターンに一致させますか?(これはサポートされていませんか?)私は各桁数を明示的にリストする方法しか知りません。私は、例えば、以下のハンドル1と2桁の数字と正しくfoo.1bar.gzを除外しますがfoo.123.gzを処理していない(と私はglob INGは場所を取るさせるための正しいことをやっていないよ!)

for f in foo.log foo.[[:digit:]].gz foo.[[:digit:]][[:digit:]].gz; do ...

100人以上の兄弟がログを返すことはないと思うかもしれませんが、私は好きではありません。 POSIX準拠したソリューションをお探し

...

編集:logrotateのconfには、いくつかのファイルのために圧縮して、他人のために圧縮されません。だから、すべての兄弟が.gzで終わるわけではありません。

答えて

1

グロブパターンは正規表現ではありません。構文はglob(7)を参照してください。

一連の数字に一致するグロブパターンはありません。あなたはfoo.[0-9]*.gzと接近することができます。

おそらく制約が与えられ、注文するためのglobパターンを使用して、シェルに頼ることができ
echo foo.[0-9]*.* | tr ' ' \\n | grep -E '[.][0-9]+([.]gz)?$' 

:それはあなたがしたくないいくつかの名前をピックアップする場合は、多分何かのように、正規表現でそれらをフィルタリングすることができますあなたは提示した。お使いのシェルがソートでソートされた順序でグロブパターンのファイル名をレンダリングするかどうかをチェックすることができます:

echo foo.[0-9]*.gz | tr \ \\n | sort -c 

しかし、あなたは極めて厳しいものでない限り、それはls -tの出力を解析することもOKです。 shellcheckからの指針は良いアドバイスです:多くの人々は、単純なglobが行うときにlsの出力を解析し、lsに依存して異なるシステム間で同じように振る舞い、エラーを招きたいと思うようです。つまり、ファイル名を時間単位でソートするだけで、出力の単一の列が生成されるようにするのがlsです。あなたがするかもしれない何かが、エラーを起こしやすいでしょう。

+0

ああ、 'foo。*。gz'は' foo.bar.log.1.gz'にマッチします。最初のログは 'foo.bar.log'の' foo.bar.log'とは無関係で、私は '[[:digit:]]'を使っているのですから... – user1011471

+0

私は自分の答えを編集しました。改訂されたパターンは役に立ちますか? –

+0

それはもっと近いです。しかし(1)時々回転した兄弟は圧縮されていないので、 '.gz'で終わらないことがあります。私はそれをその問題の可能性として述べるべきです。 'foo。[0-9] *'は 'foo.0a'にマッチするように開きます。これは私のコードのバグです。また、(2)オリジナルは 'foo.0a.gz'にマッチします。これは、ログディレクトリのファイル名は間違いありません。'[[:digit:]] 'を使ってリストを表示することは、私の場合はそれを扱うかもしれませんが、n桁ではなく、1桁と2桁の数字を扱っています。 (ログの回転はさておき、globで1〜n桁の数字を処理する方法があるのか​​どうか疑問に思います。) – user1011471

関連する問題