ファイル名を読んでファイルを移動する必要があります。システム生成ファイルを移動する必要がありますが、名前にタイムスタンプが含まれています。毎月ファイル名を読んでファイルを移動する必要があります。
ファイル名にが含まれている場合は、ディレクトリ201601*.txt
に移動します2016/January
。ファイル名に以下が含まれている場合は、ディレクトリなど201602*.txt
に移動します。2016/February
答え1
日付文字列がファイル名にあり、すべてのファイルが同じディレクトリにある場合は、次のことができます。
mv 201601*.txt 2016/January
この操作を手動で12回実行するのは面倒なことがあるので、数字とその月の名前を含むリストを作成します。
$ paste <(printf '%s\n' {01..12}) <(cal 2016 | grep -Po '\s+\K[A-Z]\w{2,}')
01 January
02 February
03 March
04 April
05 May
06 June
07 July
08 August
09 September
10 October
11 November
12 December
その後、それを解析してmv
コマンドをビルドします。
$ paste <(printf '%s\n' {01..12}) <(cal 2016 | grep -Po '\s+\K[A-Z]\w{2,}') |
while read num month; do echo mv "*2016$num*" 2016/"$month"; done
mv *201601* 2016/January
mv *201602* 2016/February
mv *201603* 2016/March
mv *201604* 2016/April
mv *201605* 2016/May
mv *201606* 2016/June
mv *201607* 2016/July
mv *201608* 2016/August
mv *201609* 2016/September
mv *201610* 2016/October
mv *201611* 2016/November
mv *201612* 2016/December
要件が満たされている場合は、削除してecho
実際にファイルを移動してください。
paste <(printf '%s\n' {01..12}) <(cal 2016 | grep -Po '\s+\K[A-Z]\w{2,}') |
while read num month; do echo mv "*2016$num*" 2016/"$month"; done
説明する
Perl準拠の正規表現()を使用して実行し、各行grep -Po '\s+\K[A-Z]\w{2,}')
の一致部分のみを印刷します()。使用される正規表現は、1つ以上の空白文字()、その後に大文字()、および2つ以上の単語文字()を検索します。 「この前の内容はすべて無視します」という意味で、コマンドが一致する文字列部分のみを印刷するようにします。grep
-P
-o
\s+
[A-Z]
\w{2,}
\K
後ろにスペース。全体のプロセスでは、月のリストのみを印刷します。
答え2
ジッシュ名前パターンに基づいてファイル名を変更する良い機能があります。zmv
。代替モードでは、$f
元の名前全体が指定されます$1
。$2
などは括弧内のグループです。月名を保存するには配列を使用してください。
autoload -U zmv
months=(January February March April May June July August September October November December)
zmv '(2016)(<1-12>)*.txt' '$1/$months[$2]/$f'
ここのパターンは単純なので、ループを使用してbashとkshに適用することはそれほど難しくありません。いくつかの点に注意する必要があります。月番号から前のゼロを削除すると、配列インデックスがゼロから始まると解釈されません。
months=(January February March April May June July August September October November December)
for f in 2016[0-9][0-9]*; do
y=${f:0:4} m=${f:4:2}
mv -- "$f" "$y/${months[${m#0}]}/$f"
done
別のアプローチはPerlの名前変更スクリプト(またはDebian バージョンまたはUnicode::バトルバージョン)。
rename 'BEGIN {@months = qw(January February March April May June July August September October November December)}
s!^([0-9]{4})([0-9]{2})!$1/$months[$2]/&!' 2016[0-9][0-9]*
答え3
以下は、bash
ファイルを繰り返してコンポーネントに一致するファイルを移動するソリューションです(yyyymm
2000〜2099の範囲の値について)。yyyy
months=('' January February March April May June July August September October November December)
for f in 20[0-9][0-9][0-3][0-9]*
do
year=$(echo "$f" | grep -Po '^20\d\d') # Extract the four digit year, 20nn
mm=$(echo "$f" | grep -Po '^(?<=20\d\d)\d\d') # Find the two digit month number 01-12
month=${months[$mm]} # Convert to a month name
test -n "$year" -a -n "$month" && echo mv "$f" "$yyyy/$month/$f"
done
実行する準備ができたら、echo
プレフィックスを削除してください。mv
すべてのファイルが次から始まることがわかっている場合、2016
これは少し簡単になります。
for f in 2016[0-3][0-9]*
do
mm=$(echo "$f" | grep -Po '^(?<=2016)\d\d') # Find the two digit month number 01-12
month=${months[$mm]} # Convert to a month name
test -n "$month" && echo mv "$f" "2016/$month/$f"
done