ファイル修正の月の2桁、年の2桁を取得しようとしても機能しません。
modified=$(stat -c %y "$line");
# modified="2018-08-22 14:39:36.400469308 -0400"
if [[ $modified =~ ".{2}(\d{2})-(\d{2})" ]]; then
echo ${BASH_REMATCH[0]}
echo ${BASH_REMATCH[1]
fi
- クンクンデモ:http://rextester.com/DJSPH52792
- 正規表現のデモ:https://regex101.com/r/UEOlMO/1
私は何が間違っていましたか?
答え1
まず、引用符は正規表現の特殊文字の意味を抑制します(オンラインマニュアル):
追加のバイナリ演算子
=~
、...を使用してパターンのすべての部分を引用して、引用符付き部分を文字列に一致させることができます。 ...正規表現構文で特殊文字を一致させるには、その文字を引用して特殊文字を削除する必要があります。
マニュアルでは、シェル構文解析と正規表現構文との競合を防ぐために、正規表現を変数に入れることをお勧めします。
第二に、\d
あなたが思うように動作せず、ただテキストと一致しますd
。
さらに、${BASH_REMATCH[0]}
インデックス付きの完全一致文字列1
とそれ以上は、キャプチャされたグループに含まれます。
また、次のように4桁の年を使用することをお勧めします。
modified=$(stat -c %y "$file")
re='^([0-9]{4})-([0-9]{2})'
if [[ $modified =~ $re ]]; then
echo "year: ${BASH_REMATCH[1]}"
echo "month: ${BASH_REMATCH[2]}"
else
echo "invalid timestamp"
fi
今日修正されたファイルの場合year: 2018
とmonth: 08
。前にゼロの数字は、シェルやその他のユーティリティで8進数として扱われます。
(1900年代の日付を処理する必要がある場合、4桁の年は問題ではなく、月単位ではなく年で識別する方が簡単です。)
答え2
これには正規表現は必要ありません。
$ touch -t 197001010000 myfile
$ ls -l myfile
-rw-rw-r-- 1 jackman jackman 0 Jan 1 1970 myfile
$ IFS='-' read -r year month _rest < <(stat -c %y myfile)
$ echo "$year:${year#??}"$month"
1970:70:01
答え3
代わりに、GNUを使用してdate
次のことを実行できます。
eval "$(date -r "$file" +'year=%Y month=%-m day=%-d')"
変更時刻の年、月、日の部分をそれぞれに保存するには$year
($month
10進整数で前に0が表示されている場合はsを削除し、2桁の年を$day
参照)。-
%-m
%-d
%y
(GNUとは異なり、stat
シンボリックリンクタイプファイルの場合、シンボリックリンク自体の修正時間ではなく、シンボリックリンクターゲットの修正時間が考慮されます。GNUではstat
これを使用できますstat -L
)。