カメラの写真を名前の付いたファイルに保存します。
192.168.33.16_01_20220723150356205_MOTION_DETECTION.jpg
各日付の各ファイルを別々のディレクトリに移動したい
このコマンドが見つかりました
find | awk '{print $1, substr($1,20,8)}'
ファイル名と目的の宛先ディレクトリのタプルを印刷します。
このコマンドの出力をコマンドにパイプできますか?
mkdir -p $2; mv $1 $2
何とか?と一緒にいることができますかxargs
?
答え1
すべてのファイルを同じディレクトリに置くことは非常に簡単な解決策です。
for i in *; do mkdir "${i:17:8}" && mv "$i" "${i:17:8}"; done
答え2
awk
プログラムを変更してシェルコマンドを出力し、次にパイプすることができますsh
。
find * | awk '{
date=substr($1,20,8)
printf "mkdir -p %s; mv %s %s\n", date, $1, date
}' | sh
上記のコードは、ファイル名にスペース(または特殊なシェル文字)が含まれていると正しく機能しませんが、すべてが質問に示されているものと同じ場合は正しく機能します。
答え3
あなたの例では192.168.33.16_01_20220723150356205_MOTION_DETECTION.jpg
日付を提供する&表現を提供しawk
ましたがsubstr($1,20,8)
、これは与えられたファイル名と一致しません。
さらに、IPは変更される可能性があり、192.168.33.16および192.168.133.116(および192.168.3.6)など、より多くの(またはより少ない)数を持つことができ、開始位置20にハードコードすることはお勧めできません。
したがって、分割には、すべてのIPケースに適用される区切り文字「_」を使用することをお勧めします。
これで日付があれば8文字だけを取得し、時間は無視しようとします。一番左にあるキャラクターたちです。
また、jpgファイルのみを処理し、ディレクトリが存在しない場合にのみmkdirを生成しようとします。
Perlを使用すると、これはすべて簡単になります。
@files_list = <*_*_*.jpg> ; # Process only *.jpg files having atleast 2 "_"
for $one_file (@files_list) {
@items = split("_",$one_file) ; # $items[0] = IP ; $items[2] = Date
$D = substr($items[2],0,8) ; # take only 8 left most Characters from Date
unless (-e "$D") {
system ("mkdir $D") ; # mkdir when the Directory is not existing
}
system ("mv $one_file $D\\$one_file") ; # move file to Directory
}
これはすでに強力ですが、必要に応じてより多くのチェックを追加できます(たとえば、ファイル名に「_」文字が4つしか含まれていないことを確認し、mkdirが_MOTION_DETECTION
成功したことを確認し、mvが成功したことを確認します)。このような拡張機能はPerlでも簡単に実装できます!
使用法:
jpgファイルを含むディレクトリでこのPerlスクリプトを実行します。
指定された基準に一致するすべてのjpgファイルが日付ごとにそのディレクトリに移動されます。
他のjpgファイルと他のすべてのファイルは変更されません。
答え4
私の考えでは、次のように入れることができます。
mkdir -p $2; mv $1 $2
スクリプトでスクリプトを実行可能にし、パイプで接続します。
find -type f -not -name script.sh | awk '{print $1, substr($1,20,8)}'|xargs ./script.sh
これにより、すでに作成した内容を使用できます。
またはスクリプトが不要な場合は、前述のように xargs を使用できます。
find -type f| awk '{print $1, substr($1,20,8)}'|xargs -l bash -c 'mkdir -p $1;mv $0 $1'