web-dev-qa-db-ja.com

角かっこ間のコンマを置き換える方法

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

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']

separated by ',',と言うMySQLコマンドを使用してファイルの内容をテーブルに挿入したいので、角かっこで囲まれたlat文字列(コンマで区切られた文字列を含む場合があります)は、MySQLがそれらを区切りたいが、テーブルにそれらのための十分な列。

角かっこ[]の間にあるコンマをセミコロン;に置き換えたい。

Linuxでこれを簡単な方法で行うにはどうすればよいですか?

編集#1

角括弧内で,で区切られた文字列の数は定義されていません。 1、2、3などになります。括弧内にある場合は常に,;に置き換える必要があります。

2
user9371654

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
0
RudiC

角かっこ内の文字列には常に一重引用符が付いているため、次のようにペアを置き換えることができます。

_$ 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/\([^\[]*\)-_[_(ゼロ以上)までのすべてに一致し、_\1_に保存します
  • \([^,]*\)-_,_までのすべてに一致し、_\2_に保存します
  • _,_-カンマに一致
  • \([^,]*\)-カンマ以外のすべてに一致し、_\3_に保存します
  • _/\1\2;\3/g_-ビットを再構築して_\1\2;\3_になり、これを貪欲に行います
1
slm

それが最後のフィールドであり、列の数が固定されている場合は、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と一緒に)、ファイルをstdinとしてそのスクリプトにフィードするか、スクリプトでファイルに名前を付けることができます。

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

これは、IFSを使用して、,で行を分割します。最初の4つのフィールドはv1..v4に割り当てられ、その後のすべては最後の変数(ここではrestと呼ばれます)に割り当てられます。次に、エコーは,で区切られた変数を出力しますが、最後の変数では;に置き換えられます。

0
RalfFriedl

ネストされた[...]がないと仮定します。

sed -e :1 -e 's/\(\[[^]]*\),/\1;/g' -e t1 < file.in > file.out
0

awkはここでは非常に優れています。フィールド区切り文字として開き角かっこを使用し、2番目のフィールドのすべてのコンマを置き換えます。

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