쉼표로 구분된 파일을 파이프로 바꾸십시오. 단, 텍스트 한정자 필드에서 쉼표나 따옴표 등을 제거하지 말고 텍스트 한정자를 제거하십시오!

쉼표로 구분된 파일을 파이프로 바꾸십시오. 단, 텍스트 한정자 필드에서 쉼표나 따옴표 등을 제거하지 말고 텍스트 한정자를 제거하십시오!

내 파일은 쉼표로 구분된 파일이고 텍스트 한정자는 ~이지만 요구 사항은 쉼표로 구분된 파일을 찾아서 |(파이프)로 구분된 파일로 바꾸고 텍스트 한정자를 제거하는 것입니다. ~ 그러나 아무것도 삭제하지 말고 특수 문자를 제거해서는 안 됩니다. 따옴표, 큰따옴표 또는 텍스트 한정자로 표시된 데이터입니다. 예: ~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

관련 정보