次の入力があります。
MX04A;
DMX04A; DMX04A; LMX04A; LMX04A;
-17.2; -15.3; -14.3; -13.6;
-16.8; -15.4; -16.0; -15.3;
LH36A;
DLH36A; DLH36A;
-11; -117.2;
-11; -17.5;
この出力を得たいです。
MX04A:DMX04A; MX04A:DMX04A; MX04A:LMX04A; MX04A:LMX04A;
-17.2; -15.3; -14.3; -13.6;
-16.8; -15.4; -16.0; -15.3;
LH36A:DLH36A; LH36A:DLH36A;
-11; -117.2;
-11; -17.5;
答え1
少なくともサンプルデータに対して動作する開始は次のとおりです。
sed -r '/[A-Z];/{N;s/([^;]+);\n([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+)/\1:\2 \1:\3 \1:\4 \1:\5/;3,$s/^/\n/};s/^/ /' input.txt
これは次のことを前提としています。
- 各レコードの最初の行には常に大文字があります。
- 各レコードの行 2 は常に行 1 に従います。
- 各レコードの行2には常に正確に4つのフィールドがあります(一般化できますが、現在は正確に4つでなければなりません)。
- 各レコードの残りの行は常に純粋な数字です。つまり、文字はありません。
- すべてのフィールドはで区切ります
space
semicolon
。 - 出力のレコードは空行で区切る必要がありますが、出力の先頭または末尾に余分な空行を含めないでください。
答え2
以下はうまくいきます:
sed -e'/-/!N;/;\n/!b' <i >o \
-e's//:/;y/ /\n/;:n' \
-e's/^\(\([^:]*\).*\)\n/\1 \2:/;tn'
または、-E
拡張正規表現構文を使用してください。(少なくともAST / BSD / GNUでは動作しますsed
):
sed -Ee'/-/!N;/;\n/!b' <i >o \
-e's//:/;y/ /\n/;:n' \
-e's/^(([^:]*).*)\n/\1 \2:/;tn'
...大きな違いはなく、長さも3文字短いです。
それとも並んで(いくつかの理由)...
sed -Ee'/-/!N;/;\n/!b' -e's//:/;y/ /\n/;:n' -e's/^(([^:]*).*)\n/\1 \2:/;tn' <i >o
出力
MX04A:DMX04A; MX04A:DMX04A; MX04A:LMX04A; MX04A:LMX04A;
-17.2; -15.3; -14.3; -13.6;
-16.8; -15.4; -16.0; -15.3;
LH36A:DLH36A; LH36A:DLH36A;
-11; -117.2;
-11; -17.5;
答え3
この質問の最初のバージョンへの回答(データ変更前)
$ awk '/^[^;]*[[:alpha:]];/{a=$1; if (NR!=1)print"";getline; gsub(/(^| )/, " "substr(a,1,length(a)-1)":");print;next} {print " "$0;}' file
MX04A:DMX04A; MX04A:DMX04A; MX04A:LMX04A; MX04A:LMX04A;
-17.2; -15.3; -14.3; -13.6;
-16.8; -15.4; -16.0; -15.3;
LH36A:DLH36A; LH36A:DLH36A; LH36A:LLH36A; LH36A:LLH36A;
-11; -117.2; 115.5; 16.8;
-11; -17.5; 113.2; 15.6;
または:
$ awk -F';' '$1 ~ /[[:alpha:]]/ {a=$1; if (NR!=1)print""; getline; gsub(/(^| )/, " " a ":"); print; next} {print " "$0;}' file
MX04A:DMX04A; MX04A:DMX04A; MX04A:LMX04A; MX04A:LMX04A;
-17.2; -15.3; -14.3; -13.6;
-16.8; -15.4; -16.0; -15.3;
LH36A:DLH36A; LH36A:DLH36A; LH36A:LLH36A; LH36A:LLH36A;
-11; -117.2; 115.5; 16.8;
-11; -17.5; 113.2; 15.6;