我有以下输入:
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'
...这并没有太大的不同,并且长度减少了三个字符。
或者在一根线上(因为某些原因)...
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;