다음 형식의 파일이 있습니다.
a1,b1,c1,d1,e1,f1
a2,b2,c2,d2,e2,f2
특정 열(예: a열과 d열, 열) 주위에 따옴표(")를 추가하고 싶습니다.원하지 않는다다른 쉼표를 포함하지만 길이가 다릅니다) 다음과 같은 결과를 얻습니다.
"a1",b1,c1,"d1",e1,f1
"a2",b2,c2,"d2",e2,f2
여러 번 반복하면서 다음과 같은 작업을 시도했습니다. 열의 시작인지 끝인지에 따라 쉼표(,)를 쉼표+따옴표(,") 또는 인용+쉼표(",)로 바꾸었습니다.
sed -E 's/(([^,]*,){1}[^,]*),/\1\,\"/g'
그러나 이는 모든 두 번째 쉼표를 쉼표와 따옴표로 바꾸는 반면, 각 명령이 따옴표가 추가되는 한 위치만 제어하기를 원합니다.
답변1
첫째, 모든 항목을 바꾸는 것을 원하지 않으며 g
이는 "전역적으로"를 의미하며 열을 지정해야 하기 때문에 모두 바꾸는 것을 원하지 않습니다. 다음으로 sed
다음과 같이 N번째 발생을 대상으로 합니다. N번째 발생은 s/old/new/N
어디에 있습니까? N
따라서 네 번째 필드를 참조하려면 다음을 수행합니다.
$ sed 's/[^,]*/"&"/4' file
a1,b1,c1,"d1",e1,f1
a2,b2,c2,"d2",e2,f2
첫 번째 필드를 변경합니다.
$ sed 's/[^,]*/"&"/1' file
"a1",b1,c1,d1,e1,f1
"a2",b2,c2,d2,e2,f2
이것은 "연산자의 왼쪽에 일치하는 모든 것"을 의미하는 &
특수 변수입니다 .sed
s///
답변2
awk
필드에 적합합니다(저 자신은 별로 좋지 않습니다. 이는 1과 4가 아니라 필드 1과 3에 작동합니다).
Awk='{
sub(/.*/, Dq "&" Dq, $1);
sub(/.*/, Dq "&" Dq, $3);
print;
}'
$ awk -v FS=, -v OFS=, -v Dq='"' "${Awk}" <<'[][]'
a1,b1,c1,d1,e1,f1
a2,b2,c2,d2,e2,f2
[][]
"a1",b1,"c1",d1,e1,f1
"a2",b2,"c2",d2,e2,f2
답변3
참조할 필드 목록 전달
awk -v fields='1,4' '
BEGIN {
FS = OFS = ","
n = split(fields, fs)
}
{ for (i=1; i<=n; i++) $(fs[i]) = "\"" $(fs[i]) "\"" }
{ print }
' file
"a1",b1,c1,"d1",e1,f1
"a2",b2,c2,"d2",e2,f2
답변4
사용 awk
하거나밀러( mlr
), 참조하려는 필드 번호는 명령줄에 쉼표로 구분된 목록으로 제공됩니다.
$ awk -F, -v f=1,4,5 'BEGIN { OFS=FS; split(f,a,",") } { for (i in a) $a[i] = "\"" $a[i] "\"" };1' file
"a1",b1,c1,"d1","e1",f1
"a2",b2,c2,"d2","e2",f2
$ mlr --nidx --fs comma put -s f=1,4,5 'begin { @a=splitnv(@f,",") } for (k,v in @a) { $[v] = "\"" . $[v] . "\"" }' file
"a1",b1,c1,"d1","e1",f1
"a2",b2,c2,"d2","e2",f2
둘 다 입력을 쉼표로 구분된 레코드 집합의 "간단한 CSV"(필드 포함 구분 기호 또는 줄 바꿈 없음)로 처리한다는 점에서 동일합니다.
주어진 숫자 문자열을 분할합니다. 여기서 각 숫자는 참조해야 하는 필드에 해당합니다. 그런 다음 필드를 반복하고 따옴표를 추가하여 각 필드를 수정합니다.