【发布时间】:2017-04-12 13:58:48
【问题描述】:
假设一个文本文件包含 x 个字符串列。
$cat file # where x=3
foo foo foo
bar bar bar
baz baz
qux
bash 中是否有办法按这些列包含的数字文本字符串(即填充的行)对这些列进行排序,同时保持每列中行的内部顺序?
$sought_command file
foo foo foo
bar bar bar
baz baz
qux
本质上,行数最多的列是第一,行数第二多的列是第二,等等。
(这个任务很容易通过R 实现,但我想知道通过bash 的解决方案。)
编辑 1:
这里有一些额外的细节:每一列至少包含一个文本字符串(即一个填充的行)。文本字符串可以构成任何字母数字组合并具有任何长度(但显然不包含空格)。输出列不得插入空白行。列分隔符没有先验限制,只要它在整个表中保持一致即可。
此任务所需要做的就是按原样移动列,以便按列长度对它们进行排序。 (我知道在 bash 中实现这个听起来比实际上要容易。)
【问题讨论】:
-
列可以有间隙吗?也就是说,在文件的第 5 行中,第 2 列是否没有条目,而第 1 列和第 3 列有条目?假设 2 列具有相同数量的条目;列是否应该保持顺序(所以如果第 2 列和第 3 列都有 4 个值,则第 2 列应该出现在第 3 列之前)?
-
一个问题是简单地确定哪些列存在,哪些不存在。默认情况下,Awk 将任何空白序列视为等同于单个空白,至少就分隔字段而言。列的宽度是否一致(您在示例数据中每个条目显示 3 个字符;真实数据是否同样严格)?您可以修改数据以便在其他空列中有一个标记(例如破折号
-)吗?那会让工作轻松很多。还是列值选项卡分开? -
@JonathanLeffler 所有列都包含至少一个文本字符串(即至少一行)。我更新了我的问题以提供所需的详细信息。
-
bash 是一个外壳。 shell 是一个环境,可以从中创建/销毁文件/进程和对工具的序列调用,它不是像您尝试那样操作文本的工具。所以,当你说你想“用 bash”做这件事时——你到底是什么意思?另外,您的列是固定宽度还是制表符分隔或什么?
-
好的,那么您正在寻找一个 awk 解决方案,因为 sed 用于在单个行上进行简单替换,而 grep 用于打印与正则表达式匹配的字符串,而这些都不是您想要的,因此留下 awk 和该解决方案将独立于您使用的任何 shell、bash 或其他方式。那么 - 是什么将样本输入中的“列”分开?标签?还是它们是固定宽度的?还是别的什么?
标签: string bash sorting awk multiple-columns