Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 按上次出现字符后的数字对文件名进行排序_Bash_Shell - Fatal编程技术网

Bash 按上次出现字符后的数字对文件名进行排序

Bash 按上次出现字符后的数字对文件名进行排序,bash,shell,Bash,Shell,我想按上次出现s后的数字对文件名进行排序,怎么做 例如: 01002M00T1relaxouspios1001a001.nii 01002M00T1relaxos301a001.nii 01002M00T1relaxos201a001.nii 01002M00T1relaxouspios901a001.nii 排序后的文件名应为: 01002M00T1relaxos201a001.nii 01002M00T1relaxos301a001.nii 01002M00T1relaxouspios90

我想按上次出现
s
后的数字对文件名进行排序,怎么做

例如:

01002M00T1relaxouspios1001a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxos201a001.nii
01002M00T1relaxouspios901a001.nii
排序后的文件名应为:

01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii
01002M00T1relaxouspios1001a001.nii
我试着用

$sort -ts -nk2,4
但它只适用于前2个文件名

例2:

01002M00T1relaxos201a001.nii 
01002M00T1relaxouspios1001a001.nii 
01002M00T130relaxos301a001.nii 
01002M00T130relaxouspios901a001.ni
预期产出:

01002M00T1relaxos201a001.nii 
01002M00T130relaxos301a001.nii 
01002M00T130relaxouspios901a001.ni
01002M00T1relaxouspios1001a001.nii 

简单地说,使用
-V
选项进行版本排序:

$ sort -V file

01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii
01002M00T1relaxouspios1001a001.nii
在发布第二个示例后进行编辑

一般情况:

$ ls | awk -Fs '{print $NF, $0}' | sort -n | awk '{print $2}'

01002M00T1relaxos201a001.nii
01002M00T130relaxos301a001.nii
01002M00T130relaxouspios901a001.ni
01002M00T1relaxouspios1001a001.nii

简单地说,使用
-V
选项进行版本排序:

$ sort -V file

01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii
01002M00T1relaxouspios1001a001.nii
在发布第二个示例后进行编辑

一般情况:

$ ls | awk -Fs '{print $NF, $0}' | sort -n | awk '{print $2}'

01002M00T1relaxos201a001.nii
01002M00T130relaxos301a001.nii
01002M00T130relaxouspios901a001.ni
01002M00T1relaxouspios1001a001.nii

您可以使用Perl或Python之类的编程语言,使您能够更多地指定要排序的内容,但如果您坚持使用BASH,则必须采用以下技巧:

您可以使用
sed
创建排序键,根据您创建的排序键进行排序,然后使用`sed:

ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2)
上面使用正则表达式的贪婪能力来获得您想要的。
\(.*s\)
将所有内容与最后的小写
s
匹配。
\(.*)
将匹配所有
s
的内容。
\1
\2
\(…\)
组中捕获的各个部分相匹配。因此,我有两条弦;第一个是文件名,第二个是排序字符串。输出如下所示:

$ ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2/'
01002M00T1relaxouspios1001a001.nii ^ 1001a001.nii
01002M00T1relaxos301a001.nii ^ 301a001.nii
01002M00T1relaxos201a001.nii ^ 201a001.nii
01002M00T1relaxouspios901a001.nii ^ 901a001.nii
现在,我可以在
^
之后对零件进行排序:

$ ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2/' | sort -t^ -k2.2
01002M00T1relaxouspios1001a001.nii ^ 1001a001.nii
01002M00T1relaxos201a001.nii ^ 201a001.nii
01002M00T1relaxos301a001.nii ^ 301a001.nii
01002M00T1relaxouspios901a001.nii ^ 901a001.nii
现在,我要做的就是删除排序键:

$ ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2/' | sort -t^ -k2.2| sed 's/ ^ .*//'
01002M00T1relaxouspios1001a001.nii
01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii

您可以使用Perl或Python之类的编程语言,使您能够更多地指定要排序的内容,但如果您坚持使用BASH,则必须采用以下技巧:

您可以使用
sed
创建排序键,根据您创建的排序键进行排序,然后使用`sed:

ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2)
上面使用正则表达式的贪婪能力来获得您想要的。
\(.*s\)
将所有内容与最后的小写
s
匹配。
\(.*)
将匹配所有
s
的内容。
\1
\2
\(…\)
组中捕获的各个部分相匹配。因此,我有两条弦;第一个是文件名,第二个是排序字符串。输出如下所示:

$ ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2/'
01002M00T1relaxouspios1001a001.nii ^ 1001a001.nii
01002M00T1relaxos301a001.nii ^ 301a001.nii
01002M00T1relaxos201a001.nii ^ 201a001.nii
01002M00T1relaxouspios901a001.nii ^ 901a001.nii
现在,我可以在
^
之后对零件进行排序:

$ ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2/' | sort -t^ -k2.2
01002M00T1relaxouspios1001a001.nii ^ 1001a001.nii
01002M00T1relaxos201a001.nii ^ 201a001.nii
01002M00T1relaxos301a001.nii ^ 301a001.nii
01002M00T1relaxouspios901a001.nii ^ 901a001.nii
现在,我要做的就是删除排序键:

$ ls | sed 's/\(.*s\)\(.*\)/\1\2 ^ \2/' | sort -t^ -k2.2| sed 's/ ^ .*//'
01002M00T1relaxouspios1001a001.nii
01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii

如果数字是uniq且足以作为索引,则有一个优雅的bash only解决方案。 想法是使用
bash数组
,而不是
关联

unset sortedlist
declare -a sortedlist
while read filename;do
    [[ $filename =~ s([0-9]+)[a-rt-z][^s]*$ ]] &&
       sortedlist[${BASH_REMATCH[1]}]=$filename
  done < <(ls)
printf "%s\n" "${sortedlist[@]}"
01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii
01002M00T1relaxouspios1001a001.nii
unset-sortedlist
声明-分类列表
读取文件名时;做
[[$filename=~s([0-9]+)[a-rt-z][^s]*$]]&&
sortedlist[${BASH_重新匹配[1]}]=$filename

完成<如果数字为uniq且足以作为索引,则有一个优雅的bash only解决方案。 想法是使用
bash数组
,而不是
关联

unset sortedlist
declare -a sortedlist
while read filename;do
    [[ $filename =~ s([0-9]+)[a-rt-z][^s]*$ ]] &&
       sortedlist[${BASH_REMATCH[1]}]=$filename
  done < <(ls)
printf "%s\n" "${sortedlist[@]}"
01002M00T1relaxos201a001.nii
01002M00T1relaxos301a001.nii
01002M00T1relaxouspios901a001.nii
01002M00T1relaxouspios1001a001.nii
unset-sortedlist
声明-分类列表
读取文件名时;做
[[$filename=~s([0-9]+)[a-rt-z][^s]*$]]&&
sortedlist[${BASH_重新匹配[1]}]=$filename

完成<否。这不起作用,例如:
01002M00T1relaxos201a001.nii
01002M00T1relaxouspios1001a001.nii
01002M00T130relaxos301a001.nii
01002M00T130relaxouspios901a001。nii
这对您给出的示例有效,顺便说一句,欢迎您。Awk的有趣解决方案。使用
$NF
并分离
s
上的字段非常有趣。否。这不起作用,例如:
01002M00T1relaxos201a001.nii
01002M00T1relaxouspios1001a001.nii
01002M00T130relaxos301a001.nii
01002M00T130relaxouspios901a001.nii
这适用于您给出的示例,顺便说一句,欢迎您。Awk的有趣解决方案。使用
$NF
并分离
s
上的字段非常有趣。非常感谢。它可以工作,除了这个小的修正:使用-nk2.2而不是-k2.2。更简单的方法是将钥匙放在前面,使用
awk
更干净,请参阅我的更新答案。非常感谢。它可以工作,除了这个小的修正:使用-nk2.2而不是-k2.2。更简单的方法是把钥匙放在前面,使用
awk
更干净,请参阅我的更新答案。我想我们对优雅的定义非常不同。是的,它是!在这种情况下,既没有用于
sed
的fork,也没有用于
排序的fork。一切都是相对的!我想我们对优雅的定义很不一样。是的,的确如此!在这种情况下,既没有用于
sed
的fork,也没有用于
排序的fork。一切都是相对的!