将块中的行转换为制表符分隔
Converting lines in chunks into tab delimited
我在 2 个块中有以下几行(实际上有 ~10K)。
在此示例中,每个块包含 3 行。块由空行分隔。所以这些块就像“段落”。
xox
91-233
chicago
koko
121-111
alabama
我想把它变成制表符分隔的行,像这样:
xox 91-233 chicago
koko 121-111 alabama
我该怎么做?
我尝试了 tr "\n" "\t"
,但它没有达到我的要求。
$ awk -F'\n' '{=} 1' RS='\n\n' OFS='\t' file
xox 91-233 chicago
koko 121-111 alabama
工作原理
Awk 将输入分成记录,并将每条记录分成字段。
-F'\n'
这告诉 awk 使用换行符作为字段分隔符。
=
这告诉 awk 将第一个字段分配给第一个字段。虽然这似乎什么都不做,但它会导致 awk 将记录视为已更改。因此,使用我们为 ORS
分配的值打印输出,输出记录分隔符。
1
这是 awk 的神秘 shorthand 打印行。
RS='\n\n'
这告诉 awk 将两个连续的换行符视为记录分隔符。
OFS='\t'
这告诉 awk 在输出时使用制表符作为字段分隔符。
另一种选择,
$ sed '/^$/d' file | pr -3ats$'\t'
xox 91-233 chicago
koko 121-111 alabama
使用 sed
删除空行并使用制表符分隔符打印到 3 列。在您的真实文件中,这应该是块中的行数。
请注意,这仅在所有块的大小相同时才有效。
此答案提供以下内容:
* 它适用于由任意数量的空行分隔的任意大小的非空行块; (相似且排在第一位)处理由 恰好一个 空行分隔的行块。
* 详细解释了awk
命令的使用。
更惯用(POSIX 兼容)awk
解决方案:
awk -v RS= -F '\n' -v OFS='\t' '=""' file
-v RS=
告诉 awk
在 段落 模式下运行:考虑 的每个 运行 nonempty 行 单个 记录; RS
是输入记录分隔符。
- 注意:这意味着该解决方案将一个或更多个空行视为分隔段落(行块); empty 表示:根本没有行内部字符,甚至没有空格。
-F '\n'
告诉 awk
将输入段落的每一行视为其自己的字段(将多行输入记录按行分成多个字段); -F
设置FS
,输入字段分隔符
-v OFS='\t'
告诉 awk
在 output 上用 \t
(制表符)分隔字段; OFS
是输出字段分隔符。
=""
看起来像空操作,但是,由于 将 分配给字段变量 </code> (记录的第一个字段), 告诉 <code>awk
重建 输入记录,使用 OFS
作为字段分隔符,从而有效地将 \n
分隔符替换为 \t
.
- 结尾的
""
是为了防止在数字上下文中评估为 0
的段落中第一行的边缘情况;附加 ""
强制处理为 字符串 ,并且任何非空字符串 - 即使它包含 "0"
- 都被视为 true在布尔上下文中 - 见下文。
鉴于 </code> 根据定义 <em>nonempty</em> 并且鉴于 <code>awk
中的赋值传递它们的值,赋值的结果=""
也是一个非空字符串;因为赋值被用作 pattern(条件),并且非空字符串被认为是 true,并且没有关联的 action block ({ ... }
), implied action 是 print - rebuilt - input record, which现在由用 制表符分隔的输入行组成 ,由默认输出记录分隔符 (ORS
)、\n
.
[=96= 终止]
另一个版本的 awk 可以做到这一点
awk '{if(NF>0){a=a"\t";i++};if(i%3==0&&NF>0){print a;a=""}}' input_file
xargs -L3 < filename.log |tr ' ' '\t'
xox 91-233 chicago
koko 121-111 alabama
我在 2 个块中有以下几行(实际上有 ~10K)。 在此示例中,每个块包含 3 行。块由空行分隔。所以这些块就像“段落”。
xox
91-233
chicago
koko
121-111
alabama
我想把它变成制表符分隔的行,像这样:
xox 91-233 chicago
koko 121-111 alabama
我该怎么做?
我尝试了 tr "\n" "\t"
,但它没有达到我的要求。
$ awk -F'\n' '{=} 1' RS='\n\n' OFS='\t' file
xox 91-233 chicago
koko 121-111 alabama
工作原理
Awk 将输入分成记录,并将每条记录分成字段。
-F'\n'
这告诉 awk 使用换行符作为字段分隔符。
=
这告诉 awk 将第一个字段分配给第一个字段。虽然这似乎什么都不做,但它会导致 awk 将记录视为已更改。因此,使用我们为
ORS
分配的值打印输出,输出记录分隔符。1
这是 awk 的神秘 shorthand 打印行。
RS='\n\n'
这告诉 awk 将两个连续的换行符视为记录分隔符。
OFS='\t'
这告诉 awk 在输出时使用制表符作为字段分隔符。
另一种选择,
$ sed '/^$/d' file | pr -3ats$'\t'
xox 91-233 chicago
koko 121-111 alabama
使用 sed
删除空行并使用制表符分隔符打印到 3 列。在您的真实文件中,这应该是块中的行数。
请注意,这仅在所有块的大小相同时才有效。
此答案提供以下内容:
* 它适用于由任意数量的空行分隔的任意大小的非空行块;
* 详细解释了awk
命令的使用。
更惯用(POSIX 兼容)awk
解决方案:
awk -v RS= -F '\n' -v OFS='\t' '=""' file
-v RS=
告诉awk
在 段落 模式下运行:考虑 的每个 运行 nonempty 行 单个 记录;RS
是输入记录分隔符。- 注意:这意味着该解决方案将一个或更多个空行视为分隔段落(行块); empty 表示:根本没有行内部字符,甚至没有空格。
-F '\n'
告诉awk
将输入段落的每一行视为其自己的字段(将多行输入记录按行分成多个字段);-F
设置FS
,输入字段分隔符-v OFS='\t'
告诉awk
在 output 上用\t
(制表符)分隔字段;OFS
是输出字段分隔符。=""
看起来像空操作,但是,由于 将 分配给字段变量</code> (记录的第一个字段), 告诉 <code>awk
重建 输入记录,使用OFS
作为字段分隔符,从而有效地将\n
分隔符替换为\t
.- 结尾的
""
是为了防止在数字上下文中评估为0
的段落中第一行的边缘情况;附加""
强制处理为 字符串 ,并且任何非空字符串 - 即使它包含"0"
- 都被视为 true在布尔上下文中 - 见下文。
- 结尾的
鉴于
[=96= 终止]</code> 根据定义 <em>nonempty</em> 并且鉴于 <code>awk
中的赋值传递它们的值,赋值的结果=""
也是一个非空字符串;因为赋值被用作 pattern(条件),并且非空字符串被认为是 true,并且没有关联的 action block ({ ... }
), implied action 是 print - rebuilt - input record, which现在由用 制表符分隔的输入行组成 ,由默认输出记录分隔符 (ORS
)、\n
.
另一个版本的 awk 可以做到这一点
awk '{if(NF>0){a=a"\t";i++};if(i%3==0&&NF>0){print a;a=""}}' input_file
xargs -L3 < filename.log |tr ' ' '\t'
xox 91-233 chicago
koko 121-111 alabama