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