web-dev-qa-db-ja.com

awk:列を分割し、区切り文字の左側を印刷し、csvの中央に貼り付けます

入力ファイル:

AAA, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

出力は次のようになります。

AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

私は次のようなものについて考えました:

awk -F, '{n=split($2,a,":"); a[n]} {$2=$NF","$2}1' OFS=,

ただし、最初の「分割」では、区切り文字の左側ではなく右側を使用し、最後のコピーではBBBではなくHHHをコピーします。

2
T-One

単一のawkを使用:

awk -F'[:,]' '{$3=$2":"$3}1' OFS=, infile
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
2
αғsнιη
$ awk -F, -v OFS=, '{ for (i=1; i<=NF; ++i) if (split($i, a, ":") > 1) $i = a[1] OFS $i } 1' file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

すべてのフィールドを反復処理する必要があり、:で分割したときに複数の文字列に分割されるフィールドを見つけた場合は、その分割文字列の最初の部分をそのフィールドの値の前に付加する必要があります。

常に2番目のフィールドになることがわかっている場合:

$ awk -F, -v OFS=, '{ split($2, a, ":"); $2 = a[1] OFS $2 } 1' file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

コードでは、nはデータが分割された文字列の数になるため、a[n]:の最後(右端)の$2区切り文字列になります。


sedの使用:

$ sed 's/\([^,: ]*\):/\1, &/g' file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

これにより、,:、またはスペースを含まない文字列が置換され、直後に:自体が2回続きます(2回目は最後の:が含まれます)。 。

(例のように)単一の置換を行うことが予想される場合は、gコマンドの最後にあるsを削除します。

0
Kusalananda

これを試して:

awk -F, '{n=split($2,a,":"); a[n]} {$2=a[1]","$2}1' OFS=, file
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH

2番目のフィールド($2=$NF","$2)でaの最初の分割を割り当てる代わりに、最後のフィールドと2番目のフィールドを$ 2($2=a[1]","$2)に割り当てる

0
Siva

単純な非awkアプローチ

$ ( cut -f1 -d: file ; cut -f2- -d, file ) | paste -sd,
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
$
0
steve

簡単なsedオプション

sed -r 's/, \w+/&&/'

\w+式は英数字(例ではBBB)に一致しますが、句読点や空白には一致しません。 &は一致全体を表します。

echo 'AAA, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH' | sed -r 's/, \w+/&&/'
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
0
roaima