sed를 사용하여 여러 열에 큰따옴표를 추가할 수 있습니까?

sed를 사용하여 여러 열에 큰따옴표를 추가할 수 있습니까?

저는 과정 수료 작업을 수행하고 있으며 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"

csvtoolcall쉘 함수와 외부 프로그램을 사용하여 라인을 구문 분석할 수도 있습니다..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로 처리할 수 있습니다.

  1. 출력 필드 구분자를 쉼표로 지정하는 입력 필드 구분자로 설정합니다.-F,
  2. 각 행에 대해 필드 1, 5, 6의 값을 원래 값으로 다시 할당하되 큰따옴표로 묶습니다. 명백한 인용 혼란은 주변 문자열을 생성하기 위해 큰따옴표를 사용하고 있고 인쇄하려는 유일한 문자열은 다음과 같기 때문입니다.큰따옴표는 이스케이프 처리해야 하므로 내가 원하는 모든 큰따옴표는 결국 "\"".
  3. 필드를 업데이트한 후 새로 결합된 문자열을 인쇄합니다.

스크립트는 다음과 같습니다

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"\""}'

시도 해봐.

관련 정보