.csv
고객 정보가 포함된 파일이 많이 있습니다 . 이 모든 파일에서 FIRSTNAME
이 열 옆에 추가 열을 추가하고 싶습니다 FULLNAME
. 이름은 첫 번째 단어를 가져와서 생성할 수 있습니다 FULLNAME
.
Jean Paul처럼 두 단어로 된 이름은 없습니다. 마지막 열에서는 필드 텍스트에 쉼표가 사용됩니다.
입력하다
COMPANY,FULLNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,[email protected],Marketing Manager,New York,Health Care,"home, workhome, work"
Company name,Firstname infix infix2 Lastname,[email protected],Marketing Manager,New York,Health Care,"home, work"
예상 출력
COMPANY,FULLNAME,FIRSTNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix infix2 Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
awk, sed 또는 다른 것을 사용하여 이 작업을 어떻게 수행할 수 있나요?
답변1
CSV를 지원하는 유틸리티 사용밀러( mlr
):
mlr --csv \
put '$FIRSTNAME = sub($FULLNAME," .*","")' then \
reorder -f COMPANY,FULLNAME,FIRSTNAME file
...질문에 있는 데이터를 바탕으로 결과는 다음과 같습니다.
COMPANY,FULLNAME,FIRSTNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, workhome, work"
Company name,Firstname infix infix2 Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Miller의 이러한 사용은 필드의 첫 번째 공백 문자 뒤의 모든 항목을 FIRSTNAME
제거하는 정규식 기반 대체를 사용하여 새 필드를 생성하는 것으로 시작됩니다.FULLNAME
COMPANY
새 필드는 마지막에 렌더링되므로 첫 번째 필드가 , FULLNAME
, 및 이 순서 대로 되도록 필드가 다시 정렬됩니다 . FIRSTNAME
나머지 필드는 원래 순서를 유지합니다.
using 표현식 대신 with 함수를 사용하여 put
필드 값을 공백으로 분할하고 첫 번째 결과 문자열을 선택할 수 있습니다.sub()
put
splitnv()
FIRSTNAME
mlr --csv \
put '$FIRSTNAME = splitnv($FULLNAME," ")[1]' then \
reorder -f COMPANY,FULLNAME,FIRSTNAME file
더 예쁜 출력을 위해:
$ mlr --icsv --opprint --barred put '$FIRSTNAME = splitnv($FULLNAME," ")[1]' then reorder -f COMPANY,FULLNAME,FIRSTNAME file
+--------------+---------------------------------+-----------+--------------------------------+-------------------+----------+-------------+----------------------+
| COMPANY | FULLNAME | FIRSTNAME | EMAIL | FUNCTION | CITY | INDUSTRY | COMMENT |
+--------------+---------------------------------+-----------+--------------------------------+-------------------+----------+-------------+----------------------+
| Company name | Firstname Lastname | Firstname | [email protected] | Marketing Manager | New York | Health Care | home, work |
| Company name | Firstname infix Lastname | Firstname | [email protected] | Marketing Manager | New York | Health Care | home, workhome, work |
| Company name | Firstname infix infix2 Lastname | Firstname | [email protected] | Marketing Manager | New York | Health Care | home, work |
+--------------+---------------------------------+-----------+--------------------------------+-------------------+----------+-------------+----------------------+
답변2
사용행복하다(이전 Perl_6)
~$ raku -MText::CSV -e 'my @a = csv(in => $*IN); \
my @b = [Z] @a>>[0..1], @a>>[1].map(*.words.[0]), @a>>[2..*]; \
@b = @b>>.[*;*]>>.Array; @b[0][2] = "FIRSTNAME"; \
csv(in => @b, out => $*OUT);' file
OP가 전체 CSV 출력을 큰따옴표로 묶기를 원하는 경우 이는 아마도 가장 쉬운 접근 방식일 것입니다(삽입된 쉼표 및/또는 공백이 있는 인용 필드가 있는 경우 RFC4180 참조).
Perl(5) 모듈은 Text::CSV_XS
높은 평가를 받고 있으며 오랜 기간 작성자/유지관리자가 Raku Text::CSV
모듈(H. Merijn Brand, 개인 커뮤니케이션)을 개발했습니다. 여기서 Raku의 Text::CSV
기능은 IO 작업, 특히 참조의 마지막 열로 제한됩니다. 그렇지 않은 경우 위의 열 작업은 표준 Raku 배열을 사용하여 수행됩니다. 그러나 이 코드의 장점은 $*IN
STDIN을 사용하는 큰따옴표로 묶은 파일 경로를 대신 사용할 수 있다는 것입니다 .
위에서 파일은 @a
첫 번째 줄에서 배열로 읽혀지고 두 번째 줄에서는 word
0으로 인덱스된 열 1의 첫 번째 항목을 꺼내서 0으로 인덱스된 열 2에 할당하고 나머지 줄 @b
은 한 줄씩 배열하십시오. 세 번째 줄은 몇 가지 관리 작업(배열 평면화, @b
요소 변경 가능화, 열 헤더 수정)을 수행합니다. 마지막으로 파일은 네 번째 줄에 출력됩니다.
입력 예:
COMPANY,FULLNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,[email protected],Marketing Manager,New York,Health Care,"home, workhome, work"
Company name,Firstname infix infix2 Lastname,[email protected],Marketing Manager,New York,Health Care,"home, work"
출력 예(위):
COMPANY,FULLNAME,FIRSTNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
"Company name","Firstname Lastname",Firstname,[email protected],"Marketing Manager","New York","Health Care","home, work"
"Company name","Firstname infix Lastname",Firstname,[email protected],"Marketing Manager","New York","Health Care","home, workhome, work"
"Company name","Firstname infix infix2 Lastname",Firstname,[email protected],"Marketing Manager","New York","Health Care","home, work"
실제로 마지막 열을 다시 참조하는 것만으로도 더 많은 작업이 필요합니다. 위의 마지막 줄을 csv(in => @b, out => $*OUT)
다음으로 바꿉니다.
.join(",").put for @b[0]; \
.join(",").put for [Z] @b[1..*]>>.[0..*-2]>>.join(","), @b[1..*]>>.[*-1].map(*.raku);'
출력 예(수정된 코드 예):
COMPANY,FULLNAME,FIRSTNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, workhome, work"
Company name,Firstname infix infix2 Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
https://datatracker.ietf.org/doc/html/rfc4180
https://github.com/Tux/CSV/blob/master/doc/Text-CSV.md
https://raku.org
답변3
사용sed
$ sed -E '2,$s/[^,]*,([^ ]*) [^,]*,/&\1,/;1s/([^,]*,){2}/&FIRSTNAME,/' input_file
COMPANY,FULLNAME,FIRSTNAME,EMAIL,FUNCTION,CITY,INDUSTRY,COMMENT
Company name,Firstname Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"
Company name,Firstname infix Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, workhome, work"
Company name,Firstname infix infix2 Lastname,Firstname,[email protected],Marketing Manager,New York,Health Care,"home, work"