将四行块合并为一行

将四行块合并为一行

我被困在这个问题上。

我有一个输入文件,看起来像

16:20:03 Buy
DRIP
AMEX
500 13,51 USD
16:05:10 Sell
SQ
NYSE
100 36,32 USD
15:48:52 Sell
NXTD
Nasdaq
500 4,99 USD
15:48:52 Sell
NXTD
Nasdaq
500 4,99 USD
15:46:07 Buy
SOXL
AMEX
50 147,7209 USD
15:40:20 Buy
TEUM
AMEX
1 700 1,36 USD
15:40:19 Buy
TEUM
AMEX
300 1,36 USD

我的目标是将每条四行记录放到一行上,例如

16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD

我知道每条记录有四行。我还知道每条记录都以 hh:mm:ss 格式的时间开始(分隔)

我尝试过各种指定 RS/FS OFS/ORS 的 awk 命令 我尝试过 sed 的不同变体,例如

sed 'N;N;s/\n/ /'

awk 仅打印第一条记录。 sed 无法将所有元素放在同一行

我可以发布我尝试过的更具体的例子。它看起来真的很简单。有谁能给我提示一下?

如果您知道另一种语言的更简单的解决方案,请随时详细说明

答案1

使用粘贴

    $ paste -d' ' - - - - <file
    16:20:03 Buy DRIP AMEX 500 13,51 USD
    16:05:10 Sell SQ NYSE 100 36,32 USD
    15:48:52 Sell NXTD Nasdaq 500 4,99 USD
    15:48:52 Sell NXTD Nasdaq 500 4,99 USD
    15:46:07 Buy SOXL AMEX 50 147,7209 USD
    15:40:20 Buy TEUM AMEX 1 700 1,36 USD
    15:40:19 Buy TEUM AMEX 300 1,36 USD

使用 sed

    $ sed 'N;N;N; s/\n/ /g' file
    16:20:03 Buy DRIP AMEX 500 13,51 USD
    16:05:10 Sell SQ NYSE 100 36,32 USD
    15:48:52 Sell NXTD Nasdaq 500 4,99 USD
    15:48:52 Sell NXTD Nasdaq 500 4,99 USD
    15:46:07 Buy SOXL AMEX 50 147,7209 USD
    15:40:20 Buy TEUM AMEX 1 700 1,36 USD
    15:40:19 Buy TEUM AMEX 300 1,36 USD

使用 awk

    $ awk '{line=line " " $0} NR%4==0{print substr(line,2); line=""}' file
    16:20:03 Buy DRIP AMEX 500 13,51 USD
    16:05:10 Sell SQ NYSE 100 36,32 USD
    15:48:52 Sell NXTD Nasdaq 500 4,99 USD
    15:48:52 Sell NXTD Nasdaq 500 4,99 USD
    15:46:07 Buy SOXL AMEX 50 147,7209 USD
    15:40:20 Buy TEUM AMEX 1 700 1,36 USD
    15:40:19 Buy TEUM AMEX 300 1,36 USD

答案2

Perl解决方案

perl -pe 's/\n/ / if $. % 4' < file
  • -p逐行读取输入,对其进行处理并将其打印回输出;
  • $.包含输入行号
  • s/\n/ /用空格替换换行符
  • %是模运算符,因此条件为“如果行号不能被四整除”

答案3

最简单的解决方案可能是exvi(即由 POSIX 指定)。

printf '%s\n' 'g/^/j4' x | ex input.txt

等效地:

printf 'g/^/j4\nx\n' | ex input.txt

解释:

printf命令仅产生以下输出,这些输出是以下命令ex

g/^/j4
x

x命令的意思是保存并退出。%p如果要将修改后的文件打印到标准输出,请替换为不是保存更改(有利于测试)。

g是全局命令,采用正则表达式(在本例中/^/当然会匹配每一行),然后是命令。该命令在正则表达式匹配的每一行上运行。

j4表示将当前行与后面三行连接起来。连接时中间加空格。


您也可以启动vi并仅键入4J然后j向下一行然后键入.,然后j向下一行然后键入.等等。但是对于ex文件末尾的任何剩余行(少于四行) )会接合在一起;与此J命令的vi情况并非如此。

答案4

$ awk '{printf $0 (NR%4?" ":"\n")}' file1
16:20:03 Buy DRIP AMEX 500 13,51 USD
16:05:10 Sell SQ NYSE 100 36,32 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:48:52 Sell NXTD Nasdaq 500 4,99 USD
15:46:07 Buy SOXL AMEX 50 147,7209 USD
15:40:20 Buy TEUM AMEX 1 700 1,36 USD
15:40:19 Buy TEUM AMEX 300 1,36 USD

相关内容