각 텍스트 줄을 쉼표로 구분하여 배열에 넣으려면 어떻게 해야 합니까?

각 텍스트 줄을 쉼표로 구분하여 배열에 넣으려면 어떻게 해야 합니까?

텍스트 파일이 있고 다음과 같이 배열을 만들고 싶습니다 array=["line1","line2",...].

이것은 내 텍스트의 첫 번째 줄입니다.

Hamlet 

William Shakespeare 

Edited Barbara B Mowat Paul Werstine 

Michael Poston Rebecca Niles 

Folger Shakespeare Library 

httpwwwfolgerdigitaltextsorgchapter5playHam 

Created Jul 31 2015 FDT version 092 

Characters Play 

line 17 POLONIUS father Ophelia Laertes councillor King Claudiusthis line substituted  
GHOST  

출력은 다음 형식이어야 합니다.

lines=["Hamlet"
,"William Shakespeare"
,"Edited Barbara B Mowat Paul Werstine "
,"Michael Poston Rebecca Niles"
,"Folger Shakespeare Library"
,"httpwwwfolgerdigitaltextsorgchapter5playHam"
,"Created Jul 31 2015 FDT version 092"
,"Characters Play"
,"line 17 POLONIUS father Ophelia Laertes councillor King Claudiusthis line substituted","GHOST"]

답변1

파일에 빈 줄이 포함되어 있지 않다고 가정합니다.

mapfile -t array <file

각 읽기 행에서 -t개행 문자를 제거합니다. array사용하는 경우 해당 줄에서 배열이 생성 됩니다 .filebash

결과를 배열 자체로 원하는지, 아니면 표시 중인 배열의 텍스트 표현으로 원하는지 명확하지 않습니다.

얻기 위해서는특별한요청한 출력:

mapfile -t array <file
printf '"%s"\n' "${array[@]}" | { mapfile -t arr; IFS=','; printf 'lines=[%s]\n' "${arr[*]}"; }

이렇게 하면 이전과 같이 행을 배열로 읽어 들일 것입니다 array. 다음 printf명령문은 배열의 각 요소 주위에 큰따옴표를 추가하고 이를 새 mapfile명령으로 보내 수정된 데이터를 새 임시 배열로 읽습니다 arr. 배열은 printf큰따옴표로 묶인 요소 사이에 쉼표를 삽입하여 요청한 방식으로 해당 요소의 형식을 지정하는 명령문에 사용됩니다.

대신 사용하십시오 awk(쉘 배열에 행을 전혀 저장하지 마십시오).

awk -v OFS=',' '
    { line[NR] = $0 }
    END {
        for (i=1; i<=NR; ++i)
            $i = "\"" line[i] "\""
        printf("lines=[%s]\n", $0);
    }' file

그러면 각 행을 awk배열로 읽어 들입니다. 마지막으로 요소에 큰따옴표를 추가하고 이를 출력 필드에 할당합니다( 루프에서 for). 이 printf명령문은 셸 코드 예제와 거의 동일한 방식으로 출력 형식을 지정합니다. $0방금 필드를 할당한 현재 레코드를 나타냅니다.

답변2

다음과 같은 도구를 사용하여 이 작업을 수행할 수 있습니다 sed.

sed - e '
       s/^[[:blank:]]*//;s/[[:blank:]]*$//
       s/"/\\"/g;H;$!d;g
        s/\n/","/g;s/.*/"&"/
 ' input

읽을 때 각 줄의 선행 및 후행 공백을 자릅니다. 큰따옴표를 모두 이스케이프 처리하세요. 예약된 공간에 추가되어 마지막 줄이 표시되면 모든 줄 바꿈이 배열 요소의 구분 기호로 변경됩니다.

답변3

IFS=$'\n'
array=( $(awk '{print "\"" $0 "\""}' input_file) )

~을 위한모든Lines input_file, 위에서 아래로 awk명령 대체 명령은 다음을 수행합니다.

  1. 한 쌍의 큰따옴표로 줄을 묶습니다.
  2. 개행 문자로 큰따옴표로 묶인 줄을 종료합니다.
  3. 결과 행을 표준 출력으로 인쇄합니다.

하지만, 표준 출력으로 인쇄하는 대신 awk전체 명령 대체를 명령 결과로 바꾸십시오. 대체는 명령 대체의 결과입니다.

다음으로, 명령 대체 결과에 토큰화를 적용합니다. 토큰화는 이 문자를 포함하지 않지만 IFS이 문자로 끝나는 IFS모든 문자 시퀀스를 고유한 "단어"로 인식합니다 . 따라서 이 특별한 경우에 "단어"는 input_file큰따옴표 쌍으로 묶인 명령의 모든 행(from) 입니다 awk.

명령 대체는 가장 바깥쪽 괄호 쌍으로 묶여 있으므로 행) ()의 결과awk

노트:

  • 배열이 할당된 후 쉘 변수를 IFS원래 값(공백, 탭 및 줄 바꿈)으로 다시 재설정할 수 있습니다.

답변4

sed - e '
   s/^[[:blank:]]*//;   # trim any leading blanks from the current line read in
   s/[[:blank:]]*$//;   # trim any trailing blanks from the current line read in
   s/"/\\"/g;           # escape any double quotes which might exist in the current line read in
   H;1h;                # append the current line to the hold space, in case of first store as is
   $!d;                 # not yet EOF, drop everything and go back to reading the next line
   g;                   # @ EOF, fetch the hold space: line1\nline2\nline3\n....\nlineEND
   s/\n/","/g;          #  line1","line2","line3","....","lineEND
   s/.*/"&"/;           # "line1","line2","line3","....","lineEND"
' input

관련 정보