awk 또는 sed를 사용하여 전체 이름에서 이름을 가져와 새 열로 추출합니다.

awk 또는 sed를 사용하여 전체 이름에서 이름을 가져와 새 열로 추출합니다.

.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()putsplitnv()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 배열을 사용하여 수행됩니다. 그러나 이 코드의 장점은 $*INSTDIN을 사용하는 큰따옴표로 묶은 파일 경로를 대신 사용할 수 있다는 것입니다 .

위에서 파일은 @a첫 번째 줄에서 배열로 읽혀지고 두 번째 줄에서는 word0으로 인덱스된 열 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"

관련 정보