2013-08-26 2 views
9

bash 스크립트를 사용하여 테이블이 포함 된 HTML을 .csv 파일로 변환하려고합니다.sed 또는 awk를 사용하여 날짜 형식을 수정하십시오.

지금까지 내가 acomplished 한 다음 단계 :

  1. 함께 (
  2. 모든 빈 줄을 제거 (sed 's/[ \t]//g'으로) 모든 공백과 탭을 제거
  3. (dos2unix와) 유닉스 형식으로 변환 sed ':a;N;$!ba;s/\n//g') (HTML 파일에 표의 각 셀에 대한 빈 줄이 있기 때문에 필요합니다. 내 잘못이 아닙니다.)
  4. 불필요한 <td><tr> 태그를 제거하십시오 (
  5. 은 물론

) sed 's/<\/tr/\n/g'와 (끝 (end-of-line) (\n) 문자로 </tr> 교환) sed 's/<\/td/,/g'로 (','로 </td> 교체), 나는 모든 이러는거야 파이프 라인. 지금까지는 훌륭하게 작동합니다. 마지막 단계는 다음과 같습니다. 테이블에 날짜가 포함 된 열이 있으며이 열의 형식은 dd/mm/yyyy이며 yyyy-mm-dd으로 변환하고 싶습니다.

(단순한) 방법 (sed 또는 awk)이 있습니까?

데이터 샘플 (전체 sed 파이프 후) :

500,2,13/09/2007,30000.00,12,B-1 
501,2,15/09/2007,14000.00,8,B-2 

가 예상 결과 :이 데이터를 가져올 필요가 있기 때문에

500,2,2007-09-13,30000.00,12,B-1 
501,2,2007-09-15,14000.00,8,B-2 

나는이 작업을 수행 할 필요가있는 이유는 MySQL에. Excel에서 파일을 열고 형식을 수동으로 변경할 수는 있지만 건너 뛰고 싶습니다.

답변

7

Awk은 아주 쉽게이 작업을 수행 할 수 있습니다

awk ' 
    BEGIN { FS = OFS = "," } 
    { split($3, date, /\//) 
     $3 = date[3] "-" date[2] "-" date[1] 
     print $0 
    } 
' infile 

그것은 산출 :

500,2,2007-09-13,30000.00,12,B-1 
501,2,2007-09-15,14000.00,8,B-2 
4
sed "s:,\([0-9]\+\)/\([0-9]\+\)/\([0-9]\+\),:,\3-\2-\1,:" 
4

awk이 작동합니다 :

echo 08/26/2013 | awk -F/ '{printf "%s-%s-%s\n",$3,$2,$1}' 

를 다음의 것 중 하나로서 bash - 단지 옵션 : 당신은 서브 쉘은 파이프 라인의 마지막 구성 요소에 사용되지 않는 ksh를 사용하는 일이 있다면

IFS=/ read m d y < <(echo 08/26/2013); echo "${y}-${m}-${d}" 
IFS=/ read m d y <<< "08/26/2013"; echo "${y}-${m}-${d}" 

, 이것은 잘 작동합니다 : bash 최근에

echo 08/26/2013 | IFS=/ read m d y; echo "${y}-${m}-${d}" 

, 스크립트에서 shopt -s lastpipe을 사용하여 위의 호출도 가능하지만 명령 행에서는 작동하지 않습니다 (아래 주석의 @ mklement0 덕택에).

내가 AWK에

+0

좋은데,이 경우에는'read'가 _subshell_에서 실행되기 때문에'read' 기반 명령이 작동하지 않습니다; 'echo '08/26/2013 '| {IFS =/읽기 m d y; echo "$ {y} - $ {m} - $ {d}"; }'또는 'IFS =/읽기 m d y <<< '08/26/2013'; echo "$ {y} - $ {m} - $ {d}"' – mklement0

+1

@ mklement0 아, 네 .... 그 작은 부분을 잊어 버렸습니다. 그것은 'ksh'에서 작동 할 것이다. 또 다른 대안으로는'IFS =/read m d y <((echo 08/26/2013)') ('echo'가 서브 쉘에있을지라도) 서브 쉘을 피할 수 있습니다. – twalberg

+0

좋은 점은, 여기서'<<<'가 아마도 가장 효율적 일 것입니다. Bash v4.2 +에서는'shopt -s lastpipe'도 사용할 수 있습니다 (그러나 스크립트에서만). 해결책 중 하나를 사용하여 답변을 업데이트 할 것을 제안 할 수 있습니까? – mklement0

7
sed -E 's,([0-9]{2})/([0-9]{2})/([0-9]{4}),\3-\2-\1,g' 
+0

일을 처리하기 위해 첫 번째 전달 예제로 붙여 넣었으며 축 어적으로 작동했습니다. 감사합니다. – Matthew

1

보정은 YYYY-MM-DD를 추구 가정 ... 나머지와 통합하는 방법을 알아 내기 위해 당신에게 그것을 떠날거야 (하지 YYYY-DD-mm)

echo 08/26/2013 | awk -F/'{printf "% s- % s- % s \ n", $ 3, $ 1, $ 2}'

2

지금까지 모든 답변은 OP의 문제와 관련이 있습니다. 물론

awk 'BEGIN{FS=","} 
    { 
     "date -d\"" $3 "\" +%Y-%m-%d" | getline mydate; 
     print $1 "," $2 "," mydate "," $4 "," $5 "," $6 
    }' 

입력 날짜 형식이 date에 의해 처리되는 경우에만이기 때문에이 방법을 작동합니다 : 여기 (-d 옵션 GNU를) 실행하는 일반적인 방법, dateawk 통해입니다. AFAICS 이것은 불행히도 dd/mm/yyyy의 경우가 아닙니다. 하나는 other commands보다 date (테스트되지 않음)보다 시도 할 수 있습니다.

편집 : 구현 된 mklement0 님의 의견.

편집 2 : 실제로 이것은 mawk으로 작동하지 않습니다. 이는 데비안의 기본값 인 awk 구현과 작동하지 않습니다. 가능한 경우 확실한 해결책은 gawk을 설치하는 것입니다.

+1

++이지만,'-d'로 인해 _GNU_'date'가 필요하다는 것을 언급해야합니다; 비슷하게,'| &'는 GNU Awk 확장이지만 실제로는 필요하지 않습니다 :'|'는 할 것입니다, 이것은 모든 Awks와 함께 작동합니다. 마지막으로, 시각적 인 명확성과 Awk의 문자열 연결이 쉘에서 다르게 작동한다는 것을 보여주기 위해 연결되는 문자열 사이에 공백을 사용하는 것이 좋습니다. 예를 들어, "date -d" "$ 3" '+ % Y- % m- % d "'(공백이있는 필드를 경계하기 위해 작은 따옴표를 추가했습니다). – mklement0

+1

@ mklement0 : 귀하의 제안에 감사드립니다, 나는 대답을 편집했습니다. 작은 따옴표는 사용하지 않으며 이스케이프 된 큰 따옴표로 바꿉니다. –

+1

답변을 업데이트 해 주셔서 고맙습니다. 그리고 작은 따옴표 오류를 잡아 주셔서 감사합니다 (스크립트를 전체적으로 작은 따옴표로 묶어 놓기 때문에 Awk 스크립트 내에서 작은 따옴표를 사용할 수 없습니다). – mklement0

관련 문제