括弧の間にカンマを置き換える方法

括弧の間にカンマを置き換える方法

次のテキストファイルがあります。

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はとても良いです。開いた角かっこをフィールド区切り文字として使用し、2番目のフィールドのすべてのカンマを置き換えます。

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

関連情報