如何在linux中用名字中的前导文本对文件进行数字排序

lqfhib0f  于 2023-08-03  发布在  Linux
关注(0)|答案(3)|浏览(105)

我期待着运行数百个文件的命名约定脚本:

hello.H    
hello.1
hello.2
...
hello.10
hello.11
...
hello.20
...
hello.100
hello.101
...
hello.200

字符串
处理文件的顺序很重要。我使用了一个for循环,它使用find/sort来运行脚本:

for i in `find ./ -name hello*.[0-9] | sort`; do ./myScript $i; done


由于文件名的数字部分前面有前导文本,因此我得到的顺序是:

hello.1
hello.10
hello.101
hello.11
hello.2
hello.20
etc.


如何对文件列表进行排序,使其在数字上准确?

ix0qys7i

ix0qys7i1#

这里的问题不在于引导文本;那就是sort是按字典顺序而不是按数字顺序排序的。即使没有我们看到的前缀:

$ for i in {1..100}; do echo $i; done | sort
1
10
100
11
12
.
.
.

字符串
如果你想按扩展名进行数字排序,你需要(a)告诉sort使用-n进行数字排序,(b)告诉sort使用-k-t选项的字段:

find ./ -name 'hello*.[0-9]*' | sort -t. -k3 -n


它产生:

./hello.1
./hello.2
./hello.3
./hello.4
./hello.5
./hello.6
./hello.7
./hello.8
./hello.9
./hello.10
.
.
.
./hello.100
.
.
.
./hello.199
./hello.200

toiithl6

toiithl62#

您需要的sortsort -t. -k3n,其中-t允许您指定分隔符'.'-k允许您根据第三个字段数字指定KEYDEF(如何排序)。(由于指定了路径的前导./部分,还在find输出中提供了'.'- thanks @larsks)

示例

使用files目录中的示例文件,例如

$ tree files
files
├── hello.1
├── hello.10
├── hello.101
├── hello.11
├── hello.2
└── hello.20

0 directories, 6 files

字符串
使用-t. -k3n排序将导致:

$ find ./files -name "hello.[0-9]*" | sort -t. -k3n
./files/hello.1
./files/hello.2
./files/hello.10
./files/hello.11
./files/hello.20
./files/hello.101

注意

在使用'.'分隔字段时,如何指定搜索路径将影响是否存在前导./。例如,搜索没有./前缀的子目录files将需要在第二个字段上排序,例如

$ find files -name "hello.[0-9]*" | sort -t. -k2n
files/hello.1
files/hello.2
files/hello.10
files/hello.11
files/hello.20
files/hello.101


如果你有问题就告诉我。
(另一种方法是awk装饰和排序,将最后一个字段$NF复制为您的排序字段)

使用awk -装饰和排序

您可以使用awk为每行添加前缀(装饰),使用'.'分隔的最后一个字段中的数字作为前缀,然后在数字排序后删除前缀。这避免了对字段进行计数,但确实增加了两个额外的子shell(通常不是问题,例如)。

find ./files -name "hello.[0-9]*" | awk -F. '{print $NF" "$0}' | sort -n | awk '{print $2}'

示例

find ./files -name "hello.[0-9]*" | awk -F. '{print $NF" "$0}' | sort -n | awk '{print $2}'
./files/hello.1
./files/hello.2
./files/hello.10
./files/hello.11
./files/hello.20
./files/hello.101


这样做的好处是如何给搜索加上前缀不再对排序有任何影响,例如。

$ find files -name "hello.[0-9]*" | awk -F. '{print $NF" "$0}' | sort -n | awk '{print $2}'
files/hello.1
files/hello.2
files/hello.10
files/hello.11
files/hello.20
files/hello.101

mbjcgjjk

mbjcgjjk3#

如果您期望的结果如下:

hello.H
hello.1
hello.2
hello.10
hello.11
hello.20
hello.100
hello.101
hello.200

字符串
为什么不直接用途:

find . -name "hello.[0-9]*"|sort -n -t. -k3


-k3沿着-t.将使用列分隔符.对第三列进行排序
您还可以尝试不同的排序方式,将数字排序的-n替换为以下任意一种:

  • 通用数字g
  • 人类-数字-h
  • 月-M
  • 数字-n
  • 随机-R
  • 版本-V

相关问题