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-05 - 07 ~ 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
정규식에서 내가 본 유일한 실수는 기본(BRE) 모드에서는 문자 그대로라는 것입니다 . 이를 논리적 "or" 등 |
으로 만들어야 합니다 .\|
\(01\|Jan\)
귀하의 버전이 이를 지원하는 경우 여러 번 호출할 이유가 없습니다. -e
한 번의 호출로 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