괄호 사이에 쉼표를 바꾸는 방법

괄호 사이에 쉼표를 바꾸는 방법

다음과 같은 텍스트 파일이 있습니다.

12.com,128.15.8.6,TEXT1,no1,['128.15.8.6']
23com,122.14.10.7,TEXT2,no2,['122.14.10.7']
45.com,91.33.10.4,TEXT3,no3,['91.33.10.4']
67.com,88.22.88.8,TEXT4,no4,['88.22.88.8', '5.112.1.10']

MySQL 명령을 사용하여 파일 내용을 테이블에 삽입하고 separated by ',',대괄호 사이의 lat 문자열(쉼표로 구분된 문자열이 포함될 수 있음)으로 인해 MySQL이 파일 내용을 구분하려고 하지만 hte 테이블에 충분한 열이 없는 문제가 발생한다고 말하고 싶기 때문입니다.

[]대괄호 사이의 쉼표를 세미콜론으로 바꾸고 싶습니다 ;.

Linux에서 간단한 방법으로 이 작업을 어떻게 수행할 수 있습니까?

편집 #1

대괄호로 구분된 문자열의 개수는 ,정의되지 않습니다. 1, 2, 3 등이 될 수 있습니다. ,대괄호 안에 있는 내용이 발견될 때마다 ;.

답변1

괄호 안의 문자열에는 항상 작은따옴표가 앞에 붙으므로 다음과 같이 간단히 쌍을 바꿀 수 있습니다.

$ sed "s/',/';/g" file
12.com,128.15.8.6,TEXT1,no1,['128.15.8.6']
23com,122.14.10.7,TEXT2,no2,['122.14.10.7']
45.com,91.33.10.4,TEXT3,no3,['91.33.10.4']
67.com,88.22.88.8,TEXT4,no4,['88.22.88.8'; '5.112.1.10']
67.com,88.22.88.8,TEXT4,no4,['88.22.88.8'; '5.112.1.10'; '1.2.3.4']
67.com,88.22.88.8,TEXT4,no4,['88.22.88.8'; '5.112.1.10'; '1.2.3.4'; '2.3.4.5']

3개 이하의 대안을 다루세요

괄호 안의 하위 문자열의 경우 길이는 최대 3( ['xxx', 'yyy', 'zzz'])입니다. sed이를 수행하려면 다음 방법을 사용할 수 있습니다 .

$ sed 's/\([^\[]*\)\([^,]*\),\([^,]*\)/\1\2;\3/g' file
12.com,128.15.8.6,TEXT1,no1;['128.15.8.6']
23com,122.14.10.7,TEXT2,no2;['122.14.10.7']
45.com,91.33.10.4,TEXT3,no3;['91.33.10.4']
67.com,88.22.88.8,TEXT4,no4,['88.22.88.8'; '5.112.1.10']
67.com,88.22.88.8,TEXT4,no4,['88.22.88.8'; '5.112.1.10'; '1.2.3.4']

어떻게 작동하나요?

이 솔루션에는 간단한 검색 및 바꾸기가 있습니다.s/.../.../g

  • s/\([^\[]*\)- 모든 항목 [(0개 이상)을 일치시키고 다음 위치에 저장합니다.\1
  • \([^,]*\)- 모든 항목을 일치시키고 ,저장합니다.\2
  • ,- 쉼표와 일치
  • \([^,]*\)- 쉼표가 아닌 모든 항목을 일치시켜 저장합니다.\3
  • /\1\2;\3/g- 비트를 \1\2;\3현재 상태로 재구성하고 탐욕스럽게 수행하십시오.

답변2

sed또한 작동할 수도 있습니다:

sed 'h; s/.*[[]/[/; s/,/;/g; x; s/[[].*//; G; s/\n// ' file

설명하다:

sed '   h;          save the entire line to hold space 
        s/.*[[]/[/  remove anything till the opening `[`
        s/,/;/g     replace ALL commas with semicolons
        x           save modified bracketed text, get back original line 
        s/[[].*//   get rid of the bracketed text
        G           append the modified text
        s/\n//      remove the <newline> char introduced by `G`
 ' file

답변3

마지막 필드이고 열 수가 고정되어 있으면 bash를 사용할 수 있습니다.

while IFS=, read v1 v2 v3 v4 rest; do
    echo "$v1,$v2,$v3,$v4,${rest//,/;}"
done

결과:

12.com,128.15.8.6,TEXT1,no1,['128.15.8.6']
23com,122.14.10.7,TEXT2,no2,['122.14.10.7']
45.com,91.33.10.4,TEXT3,no3,['91.33.10.4']
67.com,88.22.88.8,TEXT4,no4,['88.22.88.8'; '5.112.1.10']

위 명령문을 맨 위 명령문과 함께 파일에 넣고 #!/bin/bash해당 파일을 표준 입력으로 스크립트에 제공하거나 스크립트에서 파일 이름을 지정할 수 있습니다.

while IFS=, read v1 v2 v3 v4 rest; do
    echo "$v1,$v2,$v3,$v4,${rest//,/;}"
done < yourfile

IFS에서 라인을 분할 하는 데 사용됩니다 ,. 처음 4개의 필드는 v1..v4에 할당되고 그 이후의 모든 필드는 마지막 변수(여기서는 )에 할당됩니다 rest. 그런 다음 echo는 로 구분된 변수를 출력 ,하고 마지막 변수에서는 로 대체됩니다 ;.

답변4

여기서 awk는 매우 좋습니다. 여는 대괄호를 필드 구분 기호로 사용하고 두 번째 필드의 모든 쉼표를 바꿉니다.

awk 'BEGIN {FS = OFS = "["} {gsub(/,/, ";", $2)} 1' file

관련 정보