숫자가 큰따옴표로 묶이고 일부는 묶이지 않은 CSV 파일이 있습니다. 숫자의 음수 기호만 수정해야 했습니다. 뒤에 오는 음수 기호를 제거하고 시작 부분에 추가해야 했습니다.
입력 예:
column 1, column 2, column 3, column 4, column 5
12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787
예제 출력:
column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787
답변1
암소 비슷한 일종의 영양awk
해결책:
awk -v FPAT='[^,"]+|"[^"]+"' '
NR==1; NR>1{
for (i=1; i<=NF; i++) {
if ($i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/) {
sub(/-/, "", $i);
sub(/[0-9]/, "-&", $i);
}
printf "%s%s",$i,(i==NF? ORS:",")
}
}' file.csv
-v FPAT='[^,"]+|"[^"]+"'
- 필드 값을 정의하는 정규식 패턴$i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/
- 필드에 숫자와 빼기 기호가 포함되어 있는지 확인하세요-
(숫자는 큰따옴표로 묶을 수 있음).
산출:
column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787
답변2
CSV 데이터에는 CSV 파서가 필요합니다. 루비에는 다음이 하나 있습니다:
$ cat file.csv
12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787
$ ruby -rcsv -e '
CSV.foreach(ARGV.shift) do |row|
corrected = row.collect {|e| e.sub(/^([\d,.]+)-$/, "-\\1")}
puts CSV.generate_line(corrected)
end
' file.csv
-12,"-455,365.44",string with quotes-and with a comma in between,"4,432",6787
CSV 생성기는 "인용된 문자열"에 쉼표가 포함되어 있지 않기 때문에 인용할 필요가 없다고 결정했습니다.
답변3
FPAT가 없는 gawk
Awk 솔루션 :
NR==1;
NR > 1 {
$0 = $0","
while ($0) {
match($0, / *"[^"]*" *,|[^,]*,/)
f = substr($0,RSTART,RLENGTH-1) # save what matched in f
if (( f ~ /^"[0-9]([0-9,.]+[0-9]+)-"$/ ) ||
( f ~ /^[0-9]+[.]?[0-9]+-$/ ) ||
( f ~ /^[0-9]+-$/ )) {
sub(/-/, "", f);
sub(/[0-9]/, "-&", f);
}
$0 = substr($0, RLENGTH+1)
printf "%s%s", f, (0 == NF ? "\n" : ",")
}
}
제공된 예제 파일의 출력은 다음과 같습니다.
column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787
답변4
sed
지원되는 구현 에서는 문자열 필드에 포함된 큰따옴표가 다음과 같이 인코딩되고 이러한 문자열 필드에 줄바꿈이 포함되지 않는 것으로 -E
가정됩니다 .""
sed -E '
:1
s/^(("[^"]*"|[^"])*,)?([0-9.]+)-(,|$)/\1-\3\4/;
s/^(("[^"]*"|[^"])*,)?"([0-9,.]+)-"(,|$)/\1"-\3"\4/
t1' < file
입력의 성격에 따라 숫자를 더 엄격하게 일치시킬 수 있습니다. 예를 들어, ([0-9.]+)-
여기서는 on과 일치 12-
하지만 와도 일치합니다 ...-
. 해당 유형의 입력이 입력에 나타날 가능성이 있는 경우 이를 ([0-9]*\.?[0-9]+)-
다음과 같이 변경할 수 있습니다.