2016-Dec-24
テキストにasまたは存在する日付を変更しようとしていますが、2016-12-24
それをに置き換える必要があります24/12/2016
。
私ができる方法はありますかsed -i
?
入力例:
祝日または習慣宗教団体日付追加メモ *Rosh Hashanah(新年) ユダヤ教 2014年9月25日 - 2014年9月26日 指定観察者 休業日 Navaratri/Dassehra Hindu 2014年10月3日
*ヨム・キプール(贖罪日)ユダヤ人の2014年10月4日、指定された参観人の休業日
スポンサーカンファレンス名場所会議日時2017 IEEEセンサーアプリケーションシンポジウム(SAS)米国2017-03-13、2017-03-14、2017-03-15 2017 IEEE国際医療測定およびアプリケーションシンポジウム(MeMeA)アメリカ2017 2017-05-10 2017 IEEE国際計測および測定技術会議(I
これが私が今まで試したことです。
sed -i -e 's/\([0-9]\{4\}\)-\(01|Jan\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(02|Feb\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(03|Mar\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(04|Apr\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(05|May\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(06|Jun\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(07|Jul\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(08|Aug\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(09|Sep\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(10|Oct\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(11|Nov\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
sed -i -e 's/\([0-9]\{4\}\)-\(12|Dec\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
答え1
date
GNU(Linuxシステムのデフォルト)にアクセスできる場合は、次のことができます。
$ sed -E 's/(.*)-([a-z]+)(.+)/\2\3-\1/i' file |
while read d; do date -d "$d" +%d/%m/%y; done
24/12/16
24/12/16
これは行を2016-Dec-24
(Dec-24-2016
GNU Dateが理解している形式date
)に変更し、行を保持してから2016-12-24
(GNU Dateがすでに理解している形式)、各行を入力日付文字列に渡します。これは内部で行われず、Butをdate
使用しません。sed -i
ほぼ確実に最も簡単な方法です。
もしあなたなら本物これを行うには、sed
すべての月とその数を一覧表示できます。
$ for m in {1..12}; do printf '%s %s\n' "$m" $(date -d "$m/1/2016" +%b); done
1 Jan
2 Feb
3 Mar
4 Apr
5 May
6 Jun
7 Jul
8 Aug
9 Sep
10 Oct
11 Nov
12 Dec
としてmonths
保存し、繰り返してファイルを変更します。
while read num mon; do
sed -Ei "s/$mon/$num/; s#(.*)-(.*)-(.*)#\3/\2/\1#" file
done < months
またはsed実装を別々にする必要がある場合-e
:
while read num mon; do
sed -i -e "s/$mon/$num/" -Ee 's#(.*)-(.*)-(.*)#\3/\2/\1#' file
done < months
最初の置換はすべてのアルファベットの月名を対応する数字に変更し、2番目の置換は目的の形式を取得するためにコンテンツを移動します。
答え2
正規表現で私が見た唯一の間違いは、基本(BRE)モードでは文字通りであるということです。これを論理的な「or」など|
にする必要があります。\|
\(01\|Jan\)
あなたのバージョンがそれをサポートしている場合、何度も呼び出す理由はありません。-e
1回の呼び出しでsed
接続できます。-e <expr1> -e <expr2> ...
だから
sed -i \
-e 's/\([0-9]\{4\}\)-\(01\|Jan\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(02\|Feb\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(03\|Mar\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(04\|Apr\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(05\|May\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(06\|Jun\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(07\|Jul\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(08\|Aug\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(09\|Sep\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(10\|Oct\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(11\|Nov\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' \
-e 's/\([0-9]\{4\}\)-\(12\|Dec\)-\([0-9]\{2\}\)/\3\/\2\/\1/g' $1
しかし、これを行うよりエレガントな方法があります - たとえば、Perlの使用とstrptime
関数(strftime
モジュールによって提供されます):Time::Piece
perl -i -MTime::Piece -pe '
s|\d{4}-\d\d-\d\d?|Time::Piece->strptime($&, "%Y-%m-%d")->strftime("%Y/%m/%d")|ge;
s|\d{4}-...-\d\d?|Time::Piece->strptime($&, "%Y-%b-%d")->strftime("%Y/%m/%d")|ge;
' file
答え3
sed -r -i '
/([0-9]{4})-([[:alpha:]]{3})-([0-9]{2})/ {
s#([0-9]{4})-Jan-([0-9]{2})#\2/01/\1#g
s#([0-9]{4})-Feb-([0-9]{2})#\2/02/\1#g
s#([0-9]{4})-Mar-([0-9]{2})#\2/03/\1#g
s#([0-9]{4})-Apr-([0-9]{2})#\2/04/\1#g
s#([0-9]{4})-May-([0-9]{2})#\2/05/\1#g
s#([0-9]{4})-Jun-([0-9]{2})#\2/06/\1#g
s#([0-9]{4})-Jul-([0-9]{2})#\2/07/\1#g
s#([0-9]{4})-Aug-([0-9]{2})#\2/08/\1#g
s#([0-9]{4})-Sep-([0-9]{2})#\2/09/\1#g
s#([0-9]{4})-Oct-([0-9]{2})#\2/10/\1#g
s#([0-9]{4})-Nov-([0-9]{2})#\2/11/\1#g
s#([0-9]{4})-Dec-([0-9]{2})#\2/12/\1#g
}
s#([0-9]{4})-([0-9]{2})-([0-9]{2})#\3/\2/\1#g
' file