다음과 같은 텍스트 파일이 있습니다.
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