こんにちは

Linuxのコマンドでファイルを分類したいのですがやり方がよくわかりません。
記述の仕方を教えてください。特に作成日を取得してそこからフォルダを作るループがわかりません。

folderAに100件ほどファイルがあります。
ファイルの作成日に応じてフォルダに振り分け(移動)したいと思います。

1. ファイルの作成日を調べる
2. その作成日のフォルダがあれば調べる(なければ新規作成する)
例:作成日が「2014年6月27日」の場合は「2014年6月27日」というフォルダに入れる/作って入れる
3. 次のファイルをチェックする、以下ループ

ファイルは *.{MOV,AVI} です。

終わった後は
folderAの下に「2014年6月27日」や「2014年6月20日」などのフォルダができています。
folderAの直下に*.{MOV,AVI}は存在しなくなります。
1つの日付フォルダに複数のファイルが入ってもかまいません。
日付フォルダは抜けがあってもかまいません(20日と22日があって21日がないなど)

よろしくお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (4件)

ファイルの日付を取得するにはlsコマンドの「--full-time」オプションを使用します。


実行例
>ls --full-time
-rw-rw-rw- 1 hoge hoge 69 2014-06-27 14:00:00.158349853 +0900 test.txt

上記表記は一例です。
6カラム目が日付(2014-06-27)ですから、現在のディレクトリにあるファイルの日付のみを取得するのであれば、以下のコマンドで取得できますね。
>ls --full-time ./*.mov |awk '{print $6}'
これをリダイレクトでlist1.txtに落とします。
>ls --full-time ./ |awk '{print $6}' > list1.txt

日付重複の可能性がありますから、list1.txtから重複行を削除します。
sort list1.txt |uniq > sorted_list1.txt
これでsorted_list1.txt ファイルには「カレントディレクトリにある全ての.movファイルの日付一覧(重複削除済)」が完成したことになります。

あとは「このファイルの内容を1行目から順次読み込む」「読み込んだパラメータ(日付情報)にてディレクトリ作成→ファイルムーブ」すれば良いでしょう。
順次読み込みの例(参考URL)
http://www.sssg.org/blogs/hiro345/archives/6559. …
http://sweng.web.fc2.com/ja/program/bash/read-ea …

一例ですが、
filename=./sorted_list1.txt
cat ${filename} |while read line
do
mkdir $line
mv ` ls --full-time | grep $line | awk '{print $9}'` ./$line/.
done
というような感じの記述でしょうか。
(上記記述は動作確認していませんので、あくまで参考に・・・)

ls --full-time の表記はOS等によって異なりますから、awkの部分のカラムの位置等は実際に確認をしてから適宜変更する必要があります。

以上、ご参考まで。
    • good
    • 0
この回答へのお礼

ありがとうございます。

awk で欲しい情報が取得できました。
助かります。

基礎をやらないとダメだと痛感し、ちょっと厚めの自習本を買いました。

お礼日時:2014/07/12 20:19

そもそも、Unix/Linuxだと、ファイルの作成日は記録されていませんので、文字通りには不可能です。


ファイルの最終更新日でいいのなら、

cd folderA
for x in *.MOV *.AVI
do if test -f "$x"
then date=`date -r "$x" +%Y年%m月%d日`
mkdir "$date" 2>/dev/null
mv "$x" "$date"
fi
done

ただし、簡単にするために日付は2桁です(2014年06月27日など)。
上位ゼロを削除するなら、
date=`date -r "$x" +%Y年%m月%d日 | sed -e s/年0/年/ -e s/月0/月/`
です。
    • good
    • 0

Ruby スクリプトで、手軽に書くと、こんな感じでしょうか。


第1引数にディレクトリを指定します。
http://pastebin.com/UjkHSNmV
    • good
    • 0

実際にやってはいませんが…まぁ、目安として。



>1. ファイルの作成日を調べる

statコマンドで-cオプション付で指定したらよいかと。
作成日がどれにあたるのかは不明ですが。
# ModifyなのかChangeなのか…。
http://linuxjm.sourceforge.jp/html/GNU_coreutils …
%W辺りですかねぇ…。
で、UNIX TIMEなどで取得してdataコマンドで書式化してください。

>2. その作成日のフォルダがあれば調べる(なければ新規作成する)

testコマンドで有無の確認は可能かと。
# 「シェルスクリプト ディレクトリ 存在確認」辺りで検索すればそれなりに見つかるものと思われます。
ファイルの移動はmvコマンドで可能でしょう。

>3. 次のファイルをチェックする、以下ループ

普通にシェルスクリプトでループですかね。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qfind -execの末尾の{} \;の意味

末尾の{} \;を省略するとexecオプションが正しくうごきません。
これはいったい何を意味しているのでしょう?
今までは、おまじないと思っていましたが、正しい意味を知りたくなりました。

Aベストアンサー

> {}
findの条件式に一致したファイルのファイル名に置き換えられます。

> \;
「;」は、execで実行するコマンドのコマンドラインの最後を意味します。
ただ、「;」はシェルで意味を持っている文字なので、シェルによって展開されないように、つまり文字「;」そのものとするために「\」でエスケープします。

Qfind -perm -o+w -exec ls -la {} \;

タイトルのコマンドに関しまして、条件(他のユーザーに書き込み権限が与えられているファイルを検索)にマッチしたファイルの詳細を表示するコマンドで間違いないと思いますが、『{}』 は何を指しているのでしょうか?
これが、ワイルドカードの『{}』を表しており、中身を指定していないのならば、[]でも代用できるはず。と思い、

$find -perm -o+w -exec ls -la [] \;

としたら、lsコマンドに怒られてしまいました。
{}を指定しなかった場合は、期待に沿わない実行結果(マッチしたファイルの数だけ ls -la が実行される)が得られます。

『{}』は、何を意味しているのでしょうか?

ご回答の程、お願いします。

Aベストアンサー

man find
で終わるとアレなので:
-exec を使うと条件を満たす各ファイルに対してコマンドを実行しますが, そのコマンド中に {} があるとそれは「条件を満たすファイルのファイル名」に置き換わります.

Q"${0%/*}"の内容について

linuxで、シェルスクリプトを作成しているのですが、
あるページを参考にしていたところ、

"${0%/*}" 内容がでてきました。(参考ページは、cd "${0%/*}" と記述されていました。)

確認のために、下記ファイルを作成し、
echo "${0%/*}" でどういった内容になるのか確認してみました。


■シェルスクリプトの内容(ファイル:kakunin.sh)
#!/bin/sh
echo "${0%/*}"

(1)shで、シェルスクリプト実行
# sh kakunin.sh
kakunin.sh ←結果

(2).(ドット)により実行。
# ./kakunin.sh
. ←結果(. ドット)

結果が異なっています。

"${0%/*}"は何を意味しているのでしょうか。
なぜ、(1)と(2)で、実行結果が異なるのでしょうか。

御教示お願いします。

Aベストアンサー

man bash より。

${parameter%word}
${parameter%%word}
パターンに後方一致した部分を取り除く。 word が展開され、パス名展開の場合と同じようなパターンを作ります。 このパターンが parameter を展開した値の末尾の部分とマッチする場合、展開結果は parameter を展開した値から最短一致パターン (``%'' の場合) または最長一致パターン (``%%'' の場合) を取り除いたものになります。 parameter が @ または * である場合、 パターンを削除する操作は全ての位置パラメータに順番に適用され、 展開結果はリストとして得られます。 parameter が @ または * が添字になっている配列変数である場合、 パターンを削除する操作は配列の全ての要素に順番に適用され、 展開結果はリストとして得られます。

「/ があればそれとそれ以降の文字を削除する」 という意味です。
/が複数ある場合は最後の / 以降を削除。

Qawk '{print $1}' file をもっと簡単に書きたい

awkで最も頻繁に使うのが、fileのN列目だけを抜き取ってくるという使い方なんですが

awk '{print $N}' file

Nとfileという2つの引数しか使わないのでこれを
 
my_awk N file 

といった具合に間単に使える my_awk シェルを作りたいんですが、$のあたりがうまくかけません、どう直せばいいでしょうか?↓

#!/bin/csh
awk '{print $$1}' $2

Aベストアンサー

awk '{print $'"$1"'}' $2

Qfindコマンドの場合だけなぜ末尾に{}や\;が必要なのか?

なぜ findのexecの場合だけファイル名を表す{}や、コマンドの終了を表す\;が必要になるのでしょうか?
他のコマンドはわざわざ終了を明示的に示していないのにfindだけこのような記述をするのが不思議です。

Aベストアンサー

「他のコマンドを実行する」ためにfind自身への引数なのか他コマンドへの引数なのかを区別する必要があるために\;が必要で、
ファイル名を引数のどこに置くのかを指定するために{}が必要だからです

find ~ -exec hoge -xxx \;
この場合FileAが見つかったとしてFileAは引数のどこにおいてhogeを実行すべきですか?
hoge -xxx FileA ですか hoge FileA -xxx ですか?

find ~ -exec hoge {} -printf %p
-printf %p はfindのオプションとして解釈すべきですか、それともhogeの引数として渡すべきですか?それとも両方?


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報