2

我有一个包含完整路径的文件列表,我需要在 bash shell 中对其进行排序。

列表看起来像

/total/path/software/version1.2.3.4/filename.10.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.1.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.2.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.12.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.1.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.3.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.18.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.20.cfg -- infomation grepped
/real/path/software/version1.2.3.4/filename.4.cfg -- infomation grepped
/total/path/software/version1.2.3.4/filename.5.cfg -- infomation grepped

我需要先按路径排序列表,然后按文件名编号。

我试过了:

 sort -t'.' -k 1,1 -k 2,5n fileame.txt

但它只按路径排序。如果我做:

sort -t'.' -k5n filename.txt

它工作正常。按路径排序后,如何按数字顺序获取文件名?

谢谢

4

3 回答 3

1

我会创建一个排序键,然后按该排序键排序,然后删除排序键

让我们来看看...

$ while read line
do
    dirname=${line%/*}   #Directory names
    number=$(echo "$line" | sed 's/.*\.\([0-9]*\)\.cfg.*/\1/')  # File number
    printf "%-60.60s %04d | %s\n" "$dirname" "$number" "$line"
done < filetext.txt | sort | sed "s/.* \| //"

这是从每一行中读取filetext.txt并将其输送到while read line循环中。

dirname正在使用 BASH 中的功能${parameter%word}。这将获取 的值${parameter}并从右侧删除与模式匹配的最小数量word。因此,${line%/*}正在$line删除最后一个正斜杠和之后的所有字符。

number有点棘手。我注意到你.44.cfg在文件名的末尾有类似的东西。这意味着如果我能找到那个特定的模式,我就能找到文件号。我的sed命令查找一个句点,后跟零个或多个数字,后跟.cfg.,并将这些数字标记为一个分组。然后我用第一个分组替换整行,给我编号。

接下来,我使用 . 打印出目录和号码printf。我将目录名称填充为六十个字符(如果需要,可以增加),然后是一个四位数字。这将创建一个如下所示的排序键:

/full/path/software/version1.2.3.4                           0001
/full/path/software/version1.2.3.4                           0003
/full/path/software/version1.2.3.4                           0012
/full/path/software/version1.2.3.4                           0020
/long/path/software/version1.2.3.4                           0001
/long/path/software/version1.2.3.4                           0002
/long/path/software/version1.2.3.4                           0018
/real/path/software/version1.2.3.4                           0004
/total/path/software/version1.2.3.4                          0005
/total/path/software/version1.2.3.4                          0010

我将该行附加到此排序键,然后进行排序。之后,我从行中删除排序键。结果:

/full/path/software/version1.2.3.4/filename.1.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.3.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.12.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.20.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.1.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.2.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.18.cfg -- infomation grepped
/real/path/software/version1.2.3.4/filename.4.cfg -- infomation grepped
/total/path/software/version1.2.3.4/filename.5.cfg -- infomation grepped
/total/path/software/version1.2.3.4/filename.10.cfg -- infomation grepped

注意我并不像其他人在他们的答案中那样依赖于文件名的特定格式。如果你有这样的线怎么办?

/total/path/software/version1.2/filename.10.cfg -- infomation grepped

该行没有五位小数。任何试图通过句点打破字段来进行排序的东西都将失败。以上仍然有效。

于 2013-05-24T03:27:49.603 回答
1

这是你想要的 ?

 Kaizen ~
 $ for ch in `sort testfile.txt | cut -c2-3 | uniq `
 > do
 > sed -n "/^\/$ch/p" testfile.txt | sort -t'.' -k5n ;
 > done ;

结果 :

/full/path/software/version1.2.3.4/filename.1.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.3.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.12.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.20.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.1.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.2.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.18.cfg -- infomation grepped
/real/path/software/version1.2.3.4/filename.4.cfg -- infomation grepped
/total/path/software/version1.2.3.4/filename.5.cfg -- infomation grepped
/total/path/software/version1.2.3.4/filename.10.cfg -- infomation grepped

方法和你的一样,我只是添加了 sed !

于 2013-05-23T23:35:29.813 回答
1

您需要先排序filename,然后将filename数字指定为决胜局

sort -t'.' -k1,4 -k5n,5n filename.txt
/full/path/software/version1.2.3.4/filename.1.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.3.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.12.cfg -- infomation grepped
/full/path/software/version1.2.3.4/filename.20.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.1.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.2.cfg -- infomation grepped
/long/path/software/version1.2.3.4/filename.18.cfg -- infomation grepped
/real/path/software/version1.2.3.4/filename.4.cfg -- infomation grepped
/total/path/software/version1.2.3.4/filename.5.cfg -- infomation grepped
/total/path/software/version1.2.3.4/filename.10.cfg -- infomation grepped
于 2013-05-24T01:01:28.120 回答