次の形式でcsvファイルを生成するbashスクリプトがあります。
056_log_202312290735.csv
056_log_202312290736.csv
067_dat_202312290737.csv
067_dat_202312290838.csv
056_log_202312290951.csv
067_dat_202312290952.csv
056_log_202312290953.csv
...
056_log_YYYYmmddHHMM.csv
067_dat_YYYYmmddHHMM.csv
YYYYmmddHHMM
csvファイルの作成時間ではなく、csvファイル自体に含まれるデータのタイムスタンプはどこにありますか?
そのため、現在のシステム時刻(csvファイルと同じ形式、つまりYYYYmmddHHMM
)をファイル名のタイムスタンプと比較するbashスクリプトを作成したいと思います。
差が120分以上の場合は、ファイルをold_data
ディレクトリに移動する必要があります。
2つの差が120分未満の場合は、そのファイルをcurrent_data
そのディレクトリに移動する必要があります。
現在のシステム時刻である202312291048を使用して、ファイルを次のように移動する必要があります。
~/old_data/
056_log_202312290735.csv
056_log_202312290736.csv
067_dat_202312290737.csv
067_dat_202312290838.csv
~/current_data/
056_log_202312290951.csv
067_dat_202312290952.csv
056_log_202312290953.csv
これまで、私は私が望む形式を使用して現在の時間を取得できることを知っています。
CUR_TIME="`date +%Y%m%d%H%M`";
次に、次のコマンドを使用してcsvファイルからタイムスタンプを取得します。
ls 056*.csv | cut -d'_' -f 3 | cut -c -12; #get timestamps from 056 files
ls 067*.csv | cut -d'_' -f 3 | cut -c -12; #get timestamps from 067 files
それ以来、どのように進むべきかわかりません。
私が考えることができるのは次のとおりです。
#!/bin/bash
CUR_TIME=$(date +%Y%m%d%H%M);
for csvfile in *.csv
do
TIME_DIFF=0
TIMESTAMP= $(echo $csvfile | cut -d'_' -f 3 | cut -c -12)
TIME_DIFF= $CUR_TIME-$TIMESTAMP
if $TIME_DIFF >= 120
then
mv -f $csvfile ~/old_data/
else
mv -f $csvfile ~/current_data/
fi
done
答え1
たとえば、202312291607(2023/12/29 16:07)減算60は202312291547なので、実際には2023/12/29 15:47なので60分前ではありません。さて、20分前です。覚えておいて、私たちは60進システムしたがって、あなたが提案したように、単純な10進数計算を実行することはできません。一般的な解決策は、時間を次に変換することです。エポック以降そして、それを比較して秒単位の差を取得し、それを分に変換します。たとえば、
#!/bin/bash
## Get the current time in seconds since the epoch
curr_time=$(date +%s)
for csvfile in *.csv; do
## Extract the timestamp from the csv file name.
csv_date_string=$(basename "${csvfile##*_}" .csv |
sed -E 's|(....)(..)(..)(..)(..)|\1/\2/\3 \4:\5|')
## Convert the csv datestamp to seconds since the epoch
csv_time=$( date -d "$csv_date_string" +%s)
## Compare to the current time and, if more than or equal to 120
## echo the mv command, if less, echo that we do nothing.
if [[ $(( (curr_time - csv_time) / 60)) -ge 120 ]]; then
echo mv "$csvfile" old_data
else
echo "Not moving $csvfile"
fi
done
上記のスクリプトを実行し、必要に応じて動作しているように見える場合は、削除してecho
実際にmv
コマンドを実行してファイルを移動します。
ここでの秘訣は基本を使うことです。文字列演算ファイル名からタイムスタンプを抽出します。この構文は、${var##pattern}
文字列の先頭から最も長い一致を削除します。pattern
ここで、パターンは*_
_までのすべてです。彼女は次のような措置を取っています。
$ csvfile=056_log_202312290736.csv
$ echo ${csvfile##*_}
202312290736.csv
したがって、日付スタンププラスを残し、${csvfile##*_}
最後まですべてを削除してください。このコマンドはファイル名からパスを削除し、ファイル名のみを保持するように設計されていますが、提供された拡張子を削除する便利なトリックもあるため、実際のタイムスタンプを取得するにはwithを使用します。_
.csv
basename
basename
.csv
$ basename "${csvfile##*_}" .csv
202312290736
残りは比較的簡単です。if
時差が120分以上であるか簡単に確認してください。時間を秒単位で扱うので、分を取得するには60tで割る必要があります。または、120分を7200秒(120 x 60)に変換することもできます。
if [[ $(( curr_time - csv_time )) -ge 7200 ]]; then
重要:ファイルが多いため、処理に数分または数時間かかる場合がある場合は、各ファイルはスクリプトが開始された時間と比較され続けることに注意してください。つまり、スクリプトが到着したときに120分より古いが、スクリプトが起動したときにそうでないコンテンツは移動されません。これを望まない場合は、curr_time=$(date +%s)
ループ内に行を移動してファイルfor
ごとにリセットするようにしてください。