次のテキストファイルがあります。
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