쉼표로 구분된 파일을 파이프로 바꾸십시오. 단, 텍스트 한정자 필드 내의 쉼표나 따옴표 등은 제거하지 마십시오. 그러나 텍스트 한정자는 제거하십시오!

쉼표로 구분된 파일을 파이프로 바꾸십시오. 단, 텍스트 한정자 필드 내의 쉼표나 따옴표 등은 제거하지 마십시오. 그러나 텍스트 한정자는 제거하십시오!

내 파일은 쉼표로 구분된 파일이고 텍스트 한정자는 ~입니다. 하지만 요구 사항은 쉼표로 구분된 파일을 찾아서 |(파이프)로 구분된 파일로 바꾸고 텍스트 한정자 ~를 제거하는 것입니다. 그러나 따옴표나 큰따옴표를 제거해서는 안 됩니다. 텍스트 한정자에 있는 데이터 내의 특수 문자입니다. 예: ~abc",~ abc로 필요합니다",

아래는 내 소스 파일의 내용과 내가 기대하는 출력 또는 조작된 파일의 내용입니다.

소스 파일:

364034,2015652205,26722,2015,4,~C25753-4~,~TC25753,~,~2WD Double Cab 144.2" SLT,~,~Y~,40506.16,43555.00,1095.00,~043,005,006,007,003,008,016,041,012,029,068,027,028,033~,3,~2WD Double Cab 144.2"~,~SLT~,6,4,~N~,~S~,~N~,~S~,~N~,~N~,~N~,~~,~ ~,~Confirmed~,~w2015k65m22t5~,~Sierra 2500HD~,~Double Cab Standard Box 2-Wheel Drive SLT~,~Rear Wheel Drive~,~Extended Cab Pickup - Standard Bed~

정리 후에는 다음과 같은 파일이 필요합니다.

364034|2015652205|26722|2015|4|C25753-4|TC25753,|2WD Double Cab 144.2" SLT,|Y|40506.16|43555.00|1095.00|043|005|006|007|003|008|016|041|012|029|068|027|028|033|3|2WD Double Cab 144.2"|SLT|6|4|N|S|N|S|N|N|N|| |Confirmed|w2015k65m22t5|Sierra 2500HD|Double Cab Standard Box 2-Wheel Drive SLT|Rear Wheel Drive|Extended Cab Pickup - Standard Bed

여러 옵션을 사용하여 sed -i -e를 시도했지만 출력이 100% 정확하지 않습니다.

따라해 보았으나 원하는 대로 결과가 나오지 않습니다.

sed -i -e 's/,~/|/g' file_name
sed -i -e 's/~,/|/g' file_name
sed -i -e 's/~//g' file_name
sed -i -e 's/\([0-9],[0-9]\)/|/g' file_name
sed -i -e 's/\r//g' file_name

답변1

ESC=$(printf '\033')
RED="${ESC}[0;31m"
 NC="${ESC}[0m"

sed -e '
   /./!b
   /[^[:space:]]/!b

   s/.*/\
&,/

   :loop
      h
      s/\(\n\),/|\1/;                                                  # An empty field
      s/\(\n\)\([+-]\{0,1\}[.][0-9]\{1,\}\),/\2|\1/;                   # +-.NNN
      s/\(\n\)\([+-]\{0,1\}[0-9]\{1,\}\([.][0-9]*\)\{0,1\}\),/\2|\1/;  # +-NNN.MMM +-NNN. +-NNN
      s/\(\n\)~\([0-9][0-9]*\),/\2|\1/;                                # ~NNN
      s/\(\n\)\([0-9][0-9]*\)~,/\2|\1/;                                # NNN~
      s/\(\n\)~\([^~]*\)~,/\2|\1/;                                     # ~...~
      x;G
      /^\(.*\)\n\1$/{
         g;'"s/\n\([^,]*\)/${RED}\1${NC}/"'
         i\
***'"${RED}ERROR${NC}"'*** Unable to process the field shown colored.\
\
Cause of error: What this means is that this particular field is not \
\
           Fix: You should add to the sed code in the :loop label to \
                digest the able to be processed by the sed code as it stands.\
\
The record with the offending field shown colored red:\

         q
      }
      g; # all clear: recover and carry on...
   /\n$/!bloop

   s/..$//
' csv.data

일하고 있는

  • 우리는 다양한 유형의 분야에 대한 솔루션을 기반으로 합니다.
  • 비어 있거나 빈 줄을 건너뜁니다.
  • 사용된 정규식을 단순화하기 위해 ","를 추가하면 마지막에 제거됩니다.
  • 공이 굴러가도록 설정하기 위해 \n라인의 시작 부분에 마커를 배치합니다. 이 마커는 왼쪽에서 오른쪽으로 이동하며 시간에 따라 처리된 필드를 점프합니다.
  • 작업은 do-while루프에서 시작되며, 루프 본문에서는 한 번에 하나의 필드를 처리합니다. 필드 시작은 \n발생할 수 있는 다양한 필드를 신호로 표시하고 처리합니다. 매번 우리는 처리된 필드를 왼쪽으로 가져오고 로 \n교체합니다 .,|
  • 마커가 \n줄의 끝에 도달 하면 루핑이 멈추고 처음에 배치한 /\n$/더미와 마커를 제거합니다 .,

결과

364034|2015652205|26722|2015|4|C25753-4|TC25753,|2WD Double Cab 144.2" SLT,|Y|40506.16|43555.00|1095.00|043|005|006|007|003|008|016|041|012|029|068|027|028|033|3|2WD Double Cab 144.2"|SLT|6|4|N|S|N|S|N|N|N|| |Confirmed|w2015k65m22t5|Sierra 2500HD|Double Cab Standard Box 2-Wheel Drive SLT|Rear Wheel Drive|Extended Cab Pickup - Standard Bed

답변2

Perl과 같은 전용 CSV 파서를 사용하는 것이 좋습니다.텍스트::CSV

perl -MText::CSV -lne '
    BEGIN{ $csv = Text::CSV->new({ quote_char => "~" , escape_char => "~" , allow_whitespace => 1}) } 
    print join "|", $csv->fields() if $csv->parse($_)
  ' file_name
364034|2015652205|26722|2015|4|C25753-4|TC25753,|2WD Double Cab 144.2" SLT,|Y|40506.16|43555.00|1095.00|043,005,006,007,003,008,016,041,012,029,068,027,028,033|3|2WD Double Cab 144.2"|SLT|6|4|N|S|N|S|N|N|N|| |Confirmed|w2015k65m22t5|Sierra 2500HD|Double Cab Standard Box 2-Wheel Drive SLT|Rear Wheel Drive|Extended Cab Pickup - Standard Bed

관련 정보