ディレクトリ内のファイルの特定のサブセットに一致するコマンドを実行しようとしています。すべてのファイルには名前がありますタイムスタンプ.jpg、各ファイル間に約30分かかります。
に基づいてこの質問と回答echo
、私は(テストのために)次のコマンドを思いつきました。
for x in *([1510852838790,1510898258530]).jpg; do echo $x; done
ただし、これを行うと以下が出力されます(****で示されている入力番号を参照)。
1510770572978.jpg
1510770810272.jpg
1510772133873.jpg
1510772378293.jpg
1510772979803.jpg
1510773223237.jpg
1510852838790.jpg****
1510852959075.jpg
1510853079321.jpg
1510853808012.jpg
1510855019583.jpg
1510855380099.jpg
1510855983715.jpg
1510857313787.jpg
1510858282007.jpg
1510858889310.jpg
1510859009339.jpg
1510859253091.jpg
1510870852822.jpg
1510871097118.jpg
1510871335799.jpg
1510871703808.jpg
1510871823158.jpg
1510872311110.jpg
1510872553750.jpg
1510872917378.jpg
1510873159981.jpg
1510875721755.jpg
1510877181978.jpg
1510877301888.jpg
1510878157813.jpg
1510878278033.jpg
1510878522553.jpg
1510879250080.jpg
1510879738575.jpg
1510879859397.jpg
1510880105392.jpg
1510880717151.jpg
1510880957839.jpg
1510881325005.jpg
1510881570373.jpg
1510881811325.jpg
1510882295590.jpg
1510882785823.jpg
1510883275381.jpg
1510885101702.jpg
1510885222385.jpg
1510885711900.jpg
1510887172253.jpg
1510887292977.jpg
1510887538312.jpg
1510888029878.jpg
1510889975298.jpg
1510890221372.jpg
1510890709993.jpg
1510890830832.jpg
1510890951888.jpg
1510891193150.jpg
1510891313575.jpg
1510891922503.jpg
1510892537090.jpg
1510892900397.jpg
1510893021713.jpg
1510893385557.jpg
1510893992777.jpg
1510895212923.jpg
1510895333595.jpg
1510895819713.jpg
1510897039331.jpg
1510897159572.jpg
1510898133110.jpg
1510898258530.jpg****
1510900807071.jpg
1510900927933.jpg
1510902272277.jpg
1510902393272.jpg
1510902998172.jpg
1510903851131.jpg
1510905309558.jpg
1510905557228.jpg
1510907015107.jpg
1510907751301.jpg
1510907877003.jpg
1510907992905.jpg
1510908113731.jpg
1510908598199.jpg
1510908719029.jpg
1510909570015.jpg
1510909811208.jpg
1510909931529.jpg
1510910181722.jpg
1510911388852.jpg
1510911513951.jpg
1510911879905.jpg
1510912727850.jpg
1510913088390.jpg
1510913818319.jpg
1510915397801.jpg
1510917103919.jpg
1510917711228.jpg
1510917832327.jpg
1510917953273.jpg
1510918319775.jpg
1510918803832.jpg
1510918929550.jpg
1510919172181.jpg
1510919293195.jpg
1510919898053.jpg
1510922089190.jpg
1510922579951.jpg
1510923308092.jpg
1510923550590.jpg
1510923793010.jpg
1510925011829.jpg
1510925137958.jpg
1510925987153.jpg
1510927083913.jpg
1510927812212.jpg
1510928298155.jpg
1510928910223.jpg
1510929031559.jpg
1510930370780.jpg
1510930733981.jpg
1510930981902.jpg
1510932080591.jpg
1510932809212.jpg
1510933290952.jpg
1510933903131.jpg
1510935121827.jpg
1510935237921.jpg
1510935725717.jpg
1510937189535.jpg
1510937919235.jpg
1510938283032.jpg
1510938895279.jpg
1510939137978.jpg
1510939501755.jpg
1510939992901.jpg
出力リストには、ディレクトリ内の798ファイルのうち138ファイル名が含まれていますが、最初の入力番号の前と2番目の入力番号の後には追加ファイルが含まれています。なぜそんなことですか?この問題をどのように修正できますか?
答え1
[1510852838790,1510898258530]
文字セットの文字に一致する標準グローバル演算子です。[ab,c]
一致a
、b
または。,
したがって、c
orと同じです[1510852838790,1510898258530]
。つまり、合計を除くコンマまたは小数点以下の桁数と一致します。[,01235789]
[,0-357-9]
4
6
*(...)
0 以上に一致する Korn シェル glob 演算子 (およびでもサポートされています) zsh -o kshglob
。bash -O extglob
...
したがって、次の*([1510852838790,1510898258530]).jpg
すべての文字シーケンスと一致します。,01235789
.jpg
1510852838790から1510898258530の10進数で構成される文字列を一致させるには、シェル<x-y>
のglob演算子が必要ですzsh
。
printf '%s\n' <1510852838790-1510898258530>.jpg
リンクされた答えは、zsh
シェルのもう一つの機能(またではないbash
)である[x,y]
glob修飾子を表します。
glob修飾子は、(...)
名前ベースの条件に加えていくつかの条件を追加するためにglobの末尾に追加される部分です。
たとえば、次のように制限され*.jpg(.)
ますか?*.jpg
一般ファイル(ディレクトリ、シンボリックリンク、ソケット、FIFOなどは含まれません。)
*.jpg([5,10])
一致するファイルのリストから5〜10番目のファイル*.jpg
(語彙順にソート)。
zsh glob修飾子はkshglob
。 )オプション(またはkshエミュレーションモードを使用)を使用してこれを処理し、kshと同様の動作を有効にします。kshglob
bareglobqual
emulate ksh
拡張globのsに対応するksh
ものは次のとおりです(globが他の目的に使用されることを除いて、正規表現に似ています)。*(x)
zsh
x#
x*
*
bash
<x-y>
glob演算子とglob修飾子はありません。では、bash
次のことができます。
zsh -c "printf '%s\n' <1510852838790-1510898258530>.jpg"
または、以下を使用してすべてのnumber.jpg
ファイルを印刷し、出力を後処理することもできますawk
。
shopt -s extglob
printf '%s\n' *([0-9]).jpg |
awk -F. '$1 >= 1510852838790 && $1 <= 1510898258530'
とにかく、一連の数字から空白を見つけるにはawk
を使用することをお勧めします。
次のようになります(再利用に戻るzsh
):
print -l <->.jpg(n) | awk -F. '
{diff = ($0 - prev) / 1000 / 60}
NR > 1 && (diff < 29 || diff > 31) {print $0, "diff=" diff}
{prev = $0}'
答え2
ファイル名がすべてタイムスタンプの場合は、算術コンテキストで比較できます(( ))
。これは、数字で指定されたすべてのjpg
ファイルをインポートして拡張子を削除し、上限と下限と比較します。
#!/bin/bash
shopt -s extglob
for f in *([0-9]).jpg; do
timestamp="${f%%.*}"
(( "$timestamp" >= 1510852838790 && "$timestamp" <= 1510898258530 )) && echo "$f"
done
exit