동일한 폴더에 있는 여러 텍스트 파일(*.txt) 중간에 날짜 타임스탬프를 사용하여 XML 문자열 형식을 변경합니다.

동일한 폴더에 있는 여러 텍스트 파일(*.txt) 중간에 날짜 타임스탬프를 사용하여 XML 문자열 형식을 변경합니다.

다음과 같이 XML 형식의 날짜가 포함된 텍스트 파일이 많이 있습니다.

<DATA2020-04-13T08:59:05.427 />

다음과 같이 변경해야 합니다.

<DATA>2020-04-13T08:59:05.427</DATA>

노트:

날짜와 시간은 문자열마다 다르며 변경할 수 없습니다. 각 줄의 앞과 뒤에는 XML 형식의 콘텐츠가 더 많이 나옵니다. 또한 Unix를 사용하는 date것은 선택 사항이 아니며 실제로 파일 내부의 XML 문자열을 변경해야 합니다.

sed// 찾기 및 바꾸기를 사용하려고 합니다 awk. perl아마도 와일드카드를 사용할 수도 있습니다. 누구든지 이것을 달성하는 방법을 생각할 수 있습니까?

답변1

$ echo '<DATA2020-04-13T08:59:05.427 />' | sed -E 's/<DATA(20[^/]*) \/>/<DATA>\1<\/DATA>/'
<DATA>2020-04-13T08:59:05.427</DATA>

또는 이스케이프 s를 백슬래시하지 않아도 되도록 =구분 기호로 대신 사용하세요 .//

$ echo '<DATA2020-04-13T08:59:05.427 />' | sed -E 's=<DATA(202[^/]*) />=<DATA>\1</DATA>='
<DATA>2020-04-13T08:59:05.427</DATA>

이렇게 하면 읽기가 더 쉬워집니다(물론 이제 =검색 패턴과 대체 텍스트의 모든 문자를 이스케이프해야 합니다).


Perl에서도 거의 동일한 정규식을 사용할 수 있습니다(주요 차이점은 \1Perl에서 캡처 그룹을 참조하는 것이 더 좋고 정확하다는 것입니다). 구분 연산자에 대한 $1더 많은 옵션이 있습니다 (예: Match pair sum ).s{}

$ echo '<DATA2020-04-13T08:59:05.427 />' |
    perl -pe 's{<DATA(202[^/]*) />}                  
               {<DATA>$1</DATA>}'
<DATA>2020-04-13T08:59:05.427</DATA>

Perl에는 대괄호 표현식과 함께 또는 대괄호 표현식 내에서 이스케이프되지 않는 공백(개행 포함)을 /x무시하는 수정자가 있습니다 . 댓글 \도 무시합니다 #. 그 목적은 코드에서 더 읽기 쉽고 문서화된 정규식을 더 쉽게 작성할 수 있도록 하는 것입니다.

man perlrePerl 정규식에 대한 자세한 내용은 참고자료를 참조하세요.

답변2

ERE 인식 sed -E(예: GNU 또는 BSD sed)를 사용하세요.

$ sed -E 's:<(DATA)([^ ]+) />:<\1>\2</\1>:' file
<DATA>2020-04-13T08:59:05.427</DATA>

그렇지 않으면 모든 Unix 시스템의 모든 쉘에서 sed를 사용하십시오.

$ sed 's:<\(DATA\)\([^ ]*\) />:<\1>\2</\1>:' file
<DATA>2020-04-13T08:59:05.427</DATA>

답변3

사용행복하다(이전 Perl_6)

raku -pe 's:g/ \<DATA ( <+[0..9]+[-T:.]>+ ) \s\/\> /{"<DATA>"~$0~"</DATA>"}/;'  

또는

raku -pe 's:g[ "<DATA" ( <+[0..9]+[-T:.]>+ ) " />" ] = ["<DATA>"~$0~"</DATA>"];'   

입력 예:

<DATA2020-04-13T08:59:05.427 />  

예제 출력:

<DATA>2020-04-13T08:59:05.427</DATA>

위는 코드화된 답변입니다.행복하다, Perl 프로그래밍 언어 계열의 구성원입니다. 위의 두 예는 주목할 만한 네 가지 일반적인 특징을 공유합니다.

  1. 백슬래시 문자를 추측할 필요가 없습니다. 백슬래시 문자가 아닌 경우 <alnum>(영숫자 또는 밑줄) 이스케이프해야 합니다.

  2. /g지금과 같은 정규식 수정자는 global형식의 시작 부분 바로 뒤에 콜론이 옵니다. 또는 유효합니다.s///ss:globals:g

  3. Perl의 /x수정자는 이제 Raku의 기본값입니다(정규 표현식 원자 사이에 여유 공간 허용).

  4. Raku의 문자열 연결은 ~물결표를 사용하여 수행됩니다.

위의 두 예제 모두 열거된 문자 클래스를 사용합니다 <+[0..9]+[-T:.]>. 이는 매우 간단하게 숫자 [ 0..9]에 4개의 문자 [ - T : .]를 더한 것입니다. 또한 위의 첫 번째 예는 전통적인 s///대체 관용구를 따르는 반면, 위의 두 번째 예는 Raku의 새로운 "백슬래시 없음" 대체 형식( =중간에 등호 포함)을 사용하는데, 일부 독자는 이 형식이 더 읽기 쉽다고 생각할 수 있습니다.

마지막으로, 날짜/시간 추출/수정에 관심이 있는 경우 Raku에서 다음을 다루었습니다.

~$ echo '<DATA2020-04-13T08:59:05.427 />' | raku -pe 's:g[ "<DATA" ( <+[0..9]+[-T:.]>+ ) " />" ] = [DateTime($0~"Z")];'
2020-04-13T08:59:05.427000Z

~$ echo '<DATA2020-04-13T08:59:05.427 />' | raku -pe 's:g[ "<DATA" ( <+[0..9]+[-T:.]>+ ) " />" ] = [DateTime(now) - DateTime($0~"Z")];'
54862286.622457

https://docs.raku.org/언어/regexes#Enumerated_character_classes_and_ranges
https://docs.raku.org/routine/DateTime
https://raku.org

관련 정보