저는 과정 수료 작업을 수행하고 있으며 60만 행이 있는 .csv 파일의 일부 열을 조작해야 합니다. 나는 sed와 awk에 관한 여러 포럼을 검색했지만 비슷한 것을 찾을 수 없었습니다(불행히도 Linux에 대한 나의 지식은 그리 깊지 않습니다). 나는 일반적으로 하나의 열 또는 모든 열에서만 작동한다는 것을 알았습니다. 필요한 것은 첫 번째, 다섯 번째 및 여섯 번째 열에만 큰따옴표를 추가하는 것입니다.
예를 들어:
2018-03-18 4:56:17,255.255.255.255,00,ssh,admin,123
~이 되다
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"
어쩌면 데이터 마이닝을 막 시작했고 몇 주 후에 구성이 어떻게 보일지 모르기 때문에 일부 열을 변경할 수도 있습니다. 따라서 짧은 논리 구문을 만들 수 있다면 영원히 있을 것입니다. 고마워하는.
답변1
사용csvtool
유용한 format
명령이 있습니다:
csvtool format '"%1",%2,%3,%4,"%5","%6"\n' file.csv
예:
echo "2018-03-18 4:56:17,255.255.255.255,00,ssh,admin,123" |
csvtool format '"%1",%2,%3,%4,"%5","%6"\n' -
산출:
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"
csvtool
call
쉘 함수와 외부 프로그램을 사용하여 라인을 구문 분석할 수도 있습니다..CSV문서. 을 사용하면 동일한 작업을 수행 printf
하지만 "123"16진수 형식으로 실행:
echo "2018-03-18 4:56:17,255.255.255.255,00,ssh,admin,123" |
csvtool call "printf '\"%s\",%s,%s,%s,\"%s\",\"%x\"\n'" -
산출:
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","7b"
답변2
다음과 같이 awk로 처리할 수 있습니다.
- 출력 필드 구분자를 쉼표로 지정하는 입력 필드 구분자로 설정합니다.
-F,
- 각 행에 대해 필드 1, 5, 6의 값을 원래 값으로 다시 할당하되 큰따옴표로 묶습니다. 명백한 인용 혼란은 주변 문자열을 생성하기 위해 큰따옴표를 사용하고 있고 인쇄하려는 유일한 문자열은 다음과 같기 때문입니다.예큰따옴표는 이스케이프 처리해야 하므로 내가 원하는 모든 큰따옴표는 결국
"\""
. - 필드를 업데이트한 후 새로 결합된 문자열을 인쇄합니다.
스크립트는 다음과 같습니다
awk -F, 'BEGIN{ OFS=FS } {$1="\""$1"\""; $5="\""$5"\""; $6="\""$6"\""; print }' < input.csv > output.csv
더 많은 필드를 참조해야 한다고 판단되면 위의 필드 1, 5, 6과 동일한 작업을 수행하면 됩니다.
답변3
그리고perl
$ perl -F, -lane 'map {$_=qq("$_")} @F[0,4,5]; print join ",", @F' ip.txt
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"
-F,
입력 필드 구분 기호 로 사용되며,
결과는@F
배열로 제공됩니다.map {$_=qq("$_")} @F[0,4,5]
배열 요소에는 큰따옴표가 필요합니다. 인덱스는 으로 시작합니다0
. 여기서 연산자는qq
큰따옴표를 이스케이프 처리하는 것을 방지하기 위해 사용됩니다qq("$_")
."\"$_\""
print join ",", @F
,
수정된 배열을 구분 기호로 인쇄
또 다른 방법awk
$ awk -v q='"' 'BEGIN{split("1 5 6",a); FS=OFS=","}
{for(i in a) $a[i]=q $a[i] q} 1' ip.txt
"2018-03-18 4:56:17",255.255.255.255,00,ssh,"admin","123"
-v q='"'
q
변수에 큰따옴표를 값으로 저장split("1 5 6",a)
변경할 인덱스를a
배열의 값으로 저장합니다. (기본적으로 공백으로 분할, FS는 변경되지 않았습니다.)FS=OFS=","
입력/출력 구분 기호를 다음으로 변경합니다.,
for(i in a) $a[i]=q $a[i] q
필수 입력란 변경1
콘텐츠를 인쇄하는 관용적인 방법$0
답변4
쉬운 방법이 있습니다. 열 앞과 끝에 "를 넣을 때 이스케이프 문자 \를 사용하세요.
cat test.txt | awk '{ print $1" ""\""$2"\""}'
시도 해봐.