我在2个块中有以下行(实际上有~10K)。 在这个例子中,每个块包含3行。但实际上它是6行。
xox
91-233
chicago
koko
121-111
alabama
我想把它变成
xox 91-233 chicago
koko 121-111 alabama
我该怎么做?
我尝试了tr "\n" "\t"
,但没有做我想做的事。
答案 0 :(得分:4)
$ awk -F'\n' '{$1=$1} 1' RS='\n\n' OFS='\t' file
xox 91-233 chicago
koko 121-111 alabama
Awk将输入划分为记录,并将每个记录划分为字段。
-F'\n'
这告诉awk使用换行符作为字段分隔符。
$1=$1
这告诉awk将第一个字段分配给第一个字段。虽然这似乎什么都不做,但它会导致awk将记录视为已更改。因此,使用我们为ORS
指定的值(输出记录分隔符)打印输出。
1
这是用于打印线条的awk简洁速记。
RS='\n\n'
这告诉awk将两个连续的换行视为记录分隔符。
OFS='\t'
这告诉awk使用选项卡作为输出的字段分隔符。
答案 1 :(得分:3)
另一种选择,
$ sed '/^$/d' file | pr -3ats$'\t'
xox 91-233 chicago
koko 121-111 alabama
删除sed
的空行,并使用制表符分隔符打印到3列。在您的真实文件中,这应该是块中的行数。
请注意,这仅适用于所有块的大小相同的情况。
答案 2 :(得分:3)
这个答案提供以下内容:
*它适用于任何大小的非空行块,由任意数量的空行分隔; John1024's helpful answer(类似且首先出现)适用于由一个空行分隔的行块。
*它解释了详细使用的awk
命令。
更具惯用性(POSIX兼容)awk
解决方案:
awk -v RS= -F '\n' -v OFS='\t' '$1=$1""' file
-v RS=
告诉awk
以段模式运作:考虑每次非空行单> em>记录; RS
是输入记录分隔符。
-F '\n'
告诉awk
将输入段落的每一行视为自己的字段(将多行输入记录按行划分为字段); -F
设置FS
,输入字段分隔符。
-v OFS='\t'
告诉awk
在输出上用\t
(标签字符)分隔字段; OFS
是输出字段分隔符。
$1=$1""
看似无操作,但是,由于将分配给字段变量$1
(记录的第一个字段),使用awk
作为字段分隔符,OFS
重建输入记录,从而有效地将\n
分隔符替换为\t
。
""
用于防止在数字上下文中评估为0
的段落中第一行的边缘情况;附加""
强制处理为字符串,任何非空字符串 - 即使它包含"0"
- 在布尔上下文中被视为 true - 请参阅下方。鉴于$1
定义为非空,并且假定awk
中的作业通过其值,则作业$1=$1""
的结果也是非空字符串;由于赋值用作模式(条件),非空字符串被视为 true ,并且没有关联的操作块( { ... }
),隐含操作是打印 - 重建 - 输入记录,现在包含用标签分隔的输入行,由默认输出记录分隔符(ORS
),\n
终止。
答案 3 :(得分:3)
xargs -L3 < filename.log |tr ' ' '\t'
xox 91-233 chicago
koko 121-111 alabama
答案 4 :(得分:2)
另一个版本的awk来做这个
awk '{if(NF>0){a=a$1"\t";i++};if(i%3==0&&NF>0){print a;a=""}}' input_file