web-dev-qa-db-ja.com

2番目の「、」ごとに要素を区切り、bashの次の行にプッシュする

私のファイルの例は次のようになります:

201012,720,201011,119,201710,16

私が欲しい出力:

201012,720
201011,119
201710,16
5
Tejendra Khatri

Sedループを使用:

sed -e 's/,/\n/2' -e 'P;D' file

例.

$ echo '201012,720,201011,119,201710,16' | sed -e 's/,/\n/2' -e 'P;D'
201012,720
201011,119
201710,16

これにより、2番目の,\nに置き換えられ、置換が成功しなくなるまで繰り返し\nが出力および削除されます。

BSDは、改行をsコマンドの右側の\nとして理解しません。これは、ksh、bash、zshシェルの回避策です。

sed -e :a -e $'s/,/\\\n/2' -e 'P;D' file

または、(古い)sedsの一般的な解決策:

sed '
:a
s/,/\
/2
P;D
' file
5
steeldriver
$ paste -d, - - < <( tr ',' '\n' <file )
201012,720
201011,119
201710,16

または、プロセス置換なしで、

$ tr ',' '\n' <file | paste -d, - -
201012,720
201011,119
201710,16

これは、trを使用してファイル内のすべてのコンマを改行で置き換え、次にpasteを使用して、コンマで区切られた2つの列を作成します。

trが少し単純すぎると感じた場合は、同じことを行うsed 'y/,/\n/'に置き換えることができます。

5
Kusalananda

私は次のawkコマンドでこれを達成することができました:

awk -F, -v OFS=, '{for (i=1;i<=NF;i=i+2) {j=i+1; print $i,$j}}' input

これは、入力の各列をループし(反復ごとに2ずつ増加)、その列と次の隣接する列を行に出力してから、次の列に移動します。

$ cat input
201012,720,201011,119,201710,16
$ awk -F, -v OFS=, '{for (i=1;i<=NF;i=i+2) {j=i+1; print $i,$j}}' input
201012,720
201011,119
201710,16
4
jesse_b

xargsおよびprintfの使用:

xargs -d, printf '%s,%s\n' < file

出力:

201012,720
201011,119
201710,16

上記のコードは、各行に偶数のフィールドがあることを前提としています。そうでない場合、xargsは、孤立した数とダングリングコンマを出力します。しかし、このいくらか遅いコードは、ほとんどすべてのものを通過させるはずです。

tr , '\n' < file | xargs -n2 printf '%s,%s\n' | sed '$s/,$//'

-n2をある程度の最大値まで増やすことでスピードアップできますeven number、e.g。入力の数値が15桁を超えていないとします。

m=$(getconf ARG_MAX) m=$(( (m/16) + (m%2) ))
tr , '\n' < file | xargs -n"${m}" printf '%s,%s\n' | sed '$s/,$//'
1
agc

別のsedソリューション:

sed 's/\([^,]*,[^,]*\),/\1\n/g' file

これにより、2番目のカンマが改行に置き換えられます。

1
Freddy

grepを使用できます-すべてのバージョンが-oをサポートしているわけではなく、これが奇数のフィールドでは機能しないことに注意してください

grep -E -o '[^,]+,[^,]+' file

または、やりすぎ

gawk 'BEGIN{FPAT="[^,]+,[^,]+";OFS="\n"}; {$1=$1; print}' file
1
iruvar
awk -F'\n' -vRS=, '{l=$1; $0=""; getline; print l RS $1}'

または

awk -F'\n' -vRS=, '{print $1 RS (getline > 0 ? $1 : "")}'

フィールドにスペースが含まれていない場合は、-F'\n'を省略できます。または、フィールドに改行が含まれる可能性がある場合(たとえば、-F,を使用して)、レコード区切り文字と同じ値に設定します(たとえば、echo 1,2,3,4の出力で、最後のフィールドが4\nではなく4である必要があります)。

0
mosvy

シェルベース:

_(set -f; IFS=','; printf '%s,%s\n' $(< file))
_

ksh、bash、zshを使用しない場合は$(cat file)に変更します(つまり、ダッシュ他)。

builtin(ほとんどのシェル)としてprintfを実装するシェルでは、メモリ(または使用するシェルインスタンスで使用されている他のリソース制限)によって制限されます。または、execveを呼び出してコマンドラインを実行するシェル(ksh88など)のARG_MAXの値によって。

0
Isaac