テキストファイル内の引用符の間の1つまたは2つのスペースを置き換える方法

テキストファイル内の引用符の間の1つまたは2つのスペースを置き換える方法

一部のフィールドが引用符で囲まれたCSVファイルがあり、引用符内の項目は二重スペースまたは単一スペースで区切られています。カンマに置き換える必要があります。

例示ライン:

This is okay,"ABC DEF GHI",123,"This is not okay",remove,spaces,within,quotes

そしてそれはどのように見えるべきですか:

This is okay,"ABC,DEF,GHI",123,"This,is,not,okay",remove,spaces,within,quotes

答え1

perl -pe 's/".*?"/do{$a = $&; $a =~ s: +:,:g; $a}/ge;'

基本的にこれは単なるグローバル正規表現の置換ですs/regex/replacement/g。正規表現は、".*?"次から始まり終わるすべての部分文字列と一致することです。トリッキーな部分は次のとおりです。""

  • 置き換えられるのは、文字列ではなく計算された式です。 (これはe次の修飾子の意味ですg。)
  • s:regex:replacement:g評価された式は、空でない空白シーケンスをコンマで置き換えるグローバル正規表現の置換です。 (外部置換と同じ区切り文字を使用できないため、代わりに:使用します/。)
  • 内部正規表現置換を実行するには、外部置換の一致する部分文字列を$&別の変数に割り当ててから、$a内部置換を実行して$a最後に印刷する必要があります$a

まったく新しいバージョンの Perl では、補助変数への割り当てを避けることができます。修飾子を使用すると、一致する部分r文字列のコピーから直接内部置換を実行できます$&(Stéphane Chazelasのおかげで)。

perl -pe 's/".*?"/$&=~s: +:,:gr/ge;'

答え2

この無差別代入ソリューションを検討してください。

awk -F, -v OFS=, '
  {
    for(i=1;i<=NF;i++)
        if ($i ~ /^".*"$/)
                gsub(" +", ",", $i)
    print $0
  }'

awk にレコードをコンマに分割するように指示します。フィールドにカンマが含まれていると、これが壊れる可能性があることに注意してください。 - そして、OFSを使用して印刷ステートメントにフィールドをカンマで再グループ化するように指示します。for行の各フィールドを繰り返し、フィールドが^二重引用符で始まり、すべての文字を含み、.*$重引用符で終わると、グローバル$iにフィールドのすべてのスペースをコンマで置き換えます。フィールドを繰り返した後、レコード全体を印刷します($0)。

答え3

GNUの使用awk:

gawk -v RS=\" '
  NR % 2 == 0{gsub(/ +/, ",")}
  {ORS = RT; print}'

つまり、レコード区切り文字は、偶数"レコードでのみ文字とスペースを置き換えます。

RTGNU 特定の部分です。

GNUと同じsed

tr '\n"' '"\n' | sed -E '2~2s/ +/,/g' | tr '"\n' '\n"'

携帯性が向上しました。

tr '\n"' '"\n' | sed 'n;s/  */,/g' | tr '"\n' '\n"'

他のsedsで使用できますが、入力した最後の文字がそうでない場合は、問題が発生する可能性があります"

関連情報