按行的最后一个字段排序

2024-11-13 08:36:00
admin
原创
24
摘要:问题描述:对行列表进行排序的最简单方法是什么?按每行的最后一个字段进行排序?每行可能有可变数量的字段。类似于sort -k -1 是我想要的,但是 sort(1) 不采用负数来从末尾而不是从开头选择字段。我也希望能够选择字段分隔符。编辑:为问题添加一些特殊性:我想要排序的列表是路径名列表。路径名可以是任意深度...

问题描述:

对行列表进行排序的最简单方法是什么?按每行的最后一个字段进行排序?每行可能有可变数量的字段。

类似于

sort -k -1

是我想要的,但是 sort(1) 不采用负数来从末尾而不是从开头选择字段。

我也希望能够选择字段分隔符。

编辑:为问题添加一些特殊性:我想要排序的列表是路径名列表。路径名可以是任意深度,因此字段数量可变。我想按文件名组件进行排序。

这些附加信息可能会改变操作行以提取最后一个字段的方式(可以使用basename(1)),但不会改变排序要求。

例如

/a/b/c/10-foo
/a/b/c/20-bar
/a/b/c/50-baz
/a/d/30-bob
/a/e/f/g/h/01-do-this-first
/a/e/f/g/h/99-local

我希望此列表按文件名排序,所有文件名都以数字开头,表示文件的读取顺序。

我在下面添加了我的答案,这就是我目前的做法。我曾希望有一种更简单的方法 - 也许是不同的排序实用程序 - 也许不需要操作数据。


解决方案 1:

awk '{print $NF,$0}' file | sort | cut -f2- -d' '

基本上,这个命令的作用是:

  1. 重复开头的最后一个字段,以空格分隔(默认 OFS)

  2. 排序,解决重复的文件名,使用完整路径 ($0) 进行排序

  3. 截取重复的第一个字段,f2-表示从第二个字段到最后一个

解决方案 2:

这是一个 Perl 命令行(请注意,您的 shell 可能要求您转义$s):

perl -e "print sort {(split '/', $a)[-1] <=> (split '/', $b)[-1]} <>"

只需将列表放入其中,或者如果列表在文件中,则将文件名放在命令行的末尾。

请注意,该脚本实际上不会改变数据,因此您不必小心使用什么分隔符。

以下是示例输出:

>perl -e "打印排序 {(拆分'/',$a)[-1] <=> (拆分'/',$b)[-1]} " files.txt
/a/e/f/g/h/01-先做这件事
/a/b/c/10-foo
/a/b/c/20-巴
/a/d/30-bob
/a/b/c/50-baz
/a/e/f/g/h/99-本地

解决方案 3:

类似这样的

awk '{print $NF"|"$0}' file | sort -t"|" -k1 | awk -F"|" '{print $NF }'

解决方案 4:

perl 中的一个单行命令用于反转行中字段的顺序:

perl -lne 'print join " ", reverse split / /'

你可以使用它一次,将输出通过管道传送给 sort,然后将其通过管道传送回去,这样你就可以实现你想要的效果。你可以更改/ // +/这样它就可以压缩空格。当然,你可以自由地使用任何你想要的正则表达式来分割行。

解决方案 5:

我认为唯一的解决办法是使用awk

  1. 使用 将最后一个字段放在前面awk

  2. 对行进行排序。

  3. 将第一个字段重新放到最后。

解决方案 6:

将该行中的最后一个分隔符替换为列表中未出现的另一个分隔符,并使用该另一个分隔符作为 sort(1) 分隔符对第二个字段进行排序,然后还原分隔符更改。

delim=/
new_delim=" "
cat $list \n| sed "s|(.*)$delim|$new_delim|" \n| sort -t"$new_delim" -k 2,2 \n| sed "s|$new_delim|$delim|"

问题在于要知道要使用哪个未出现在列表中的分隔符。您可以多次遍历列表,然后 grep 连续可能的分隔符,但这一切都相当麻烦 - 尤其是当“按行的最后一个字段排序”的概念表达得如此简单,而解决方案却并非如此时。

编辑:$new_delim 使用的一个安全分隔符是 NUL,因为它不能出现在文件名中,但我不知道如何将 NUL 字符放入 bourne/POSIX shell 脚本(不是 bash)以及 sort 和 sed 是否能正确处理它。

解决方案 7:

#!/usr/bin/ruby

f = ARGF.read
lines = f.lines

broken = lines.map {|l| l.split(/:/) }

sorted = broken.sort {|a, b|
    a[-1] <=> b[-1]
}

fixed = sorted.map {|s| s.join(":") }

puts fixed

如果所有答案都涉及 perl 或 awk,不妨用脚本语言解决整个问题。(顺便说一句,我首先尝试使用 Perl,但很快想起我不喜欢 Perl 的列表列表。我很想看看 Perl 大师的版本。)

解决方案 8:

我希望此列表按文件名排序,所有文件名都以数字开头,表示文件的读取顺序。

find . | sed 's#.*/##' | sort

sed 替换以斜杠结尾的结果列表中的所有部分。文件名是剩下的,您可以根据该文件名进行排序。

解决方案 9:

这是一个 python 单行版本,请注意,它假定该字段是整数,您可以根据需要进行更改。

echo file.txt | python3 -c 'import sys; list(map(sys.stdout.write, sorted(sys.stdin, key=lambda x: int(x.rsplit(" ", 1)[-1]))))'

解决方案 10:

| sed "s#(.*)/#"\\$'x7F'# \n| sort -t\\$'x7F' -k2,2 \n| sed s#\\$'x7F'"#/#"

仍然比 sort(1) 的简单负字段索引差得多,但在这种情况下使用 DEL 字符作为分隔符不会引起任何问题。

我也喜欢它的对称性。

解决方案 11:

sort如果我没记错的话,可以使用选项指定分隔符-t。要计算最后一个字段,您可以执行一些操作,例如计算一行中的分隔符数量并求和。例如,如下所示(假设分隔符为“:”):

d=`head -1 FILE | tr -cd :  | wc -c`
d=`expr $d + 1`

$d现在包含最后一个字段索引)。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用