入力ファイル:
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をコピーします。
単一のawk
を使用:
awk -F'[:,]' '{$3=$2":"$3}1' OFS=, infile
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
$ 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
を削除します。
これを試して:
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
)に割り当てる
単純な非awkアプローチ
$ ( cut -f1 -d: file ; cut -f2- -d, file ) | paste -sd,
AAA, BBB, BBB:XXX, CCC, DDD, EEE, FFF, GGG, HHH
$
簡単な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