我使用以下命令循环目录中的所有文件:
for i in *.fas; do some_code; done;
但是,我得到这样的命令:
vvchr1.fas
vvchr10.fas
vvchr11.fas
而不是vvchr1.fas,vvchr2.fas,vvchr3.fas,什么是数字顺序。
我尝试过sort命令,但没有成功。
答案 0 :(得分:82)
for i in `ls *.fas | sort -V`; do some_code; done;
其中sort -V
根据man sort
版本排序 - 文本中的一种自然类型(版本)数字
仅使用ls
:
for i in `ls -v *.fas`; do echo $i; done;
答案 1 :(得分:4)
您将按ASCII顺序获取文件。这意味着vvchr10*
出现在vvchr2*
之前。我意识到你不能重命名你的文件(我的生物信息学大脑告诉我它们包含染色体数据,我们根本就不称为染色体1“chr01”),所以这是另一个解决方案(不使用sort -V
我可以'找到我正在使用的任何操作系统):
ls *.fas | sed 's/^\([^0-9]*\)\([0-9]*\)/\1 \2/' | sort -k2,2n | tr -d ' ' |
while read filename; do
# do work with $filename
done
这有点令人费解,不适用于包含空格的文件名。
另一种解决方案:假设我们希望以大小顺序迭代文件,这可能更适合某些生物信息学任务:
du *.fas | sort -k2,2n |
while read filesize filename; do
# do work with $filename
done
要反转排序,只需在r
之后添加-k2,2n
(以获取-k2,2nr
)。
答案 2 :(得分:3)
使用选项 sort -g ,它会根据一般数值
进行比较 for FILE in `ls ./raw/ | sort -g`; do echo "$FILE"; done
0.log 1.登录 2.登录 ... 10.log 11.log
这仅在文件名为数字时才有效。如果它们是字符串,您将按字母顺序获取它们。 E.g:
for FILE in `ls ./raw/* | sort -g`; do echo "$FILE"; done
生/ 0.log 生/ 10.log 生/ 11.log ... 生/ 2.登录
答案 3 :(得分:1)
您的意思是编号为10的文件位于列表中编号为3的文件之前?多数民众赞成因为ls
对结果的排序非常简单,因此something-10.whatever
小于而不是something-3.whatever
。
一种解决方案是重命名所有文件,使其具有相同的位数(其中包含单个数字的文件以数字中的0
开头)。
答案 4 :(得分:1)
while IFS= read -r file ; do
ls -l "$file" # or whatever
done < <(find . -name '*.fas' 2>/dev/null | sed -r -e 's/([0-9]+)/ \1/' | sort -k 2 -n | sed -e 's/ //;'
解决问题,假设文件命名保持一致,不依赖于最新版本的GNU sort
,不依赖于读取ls
的输出并且不会成为受害者对于管道问题。
答案 5 :(得分:0)
喜欢@ Kusalananda的解决方案(也许更容易记住?)但是要适应所有文件(?):
array=("$(ls |sed 's/[^0-9]*\([0-9]*\)\..*/\1 &/'| sort -n | sed 's/^[^ ]* //')")
for x in "${array[@]}";do echo "$x";done
实质上添加排序键,排序,删除排序键。
编辑:将评论移至适当的解决方案
答案 6 :(得分:0)
使用sort -rh和while循环
du -sh * | sort -rh | grep -P "avi$" |awk '{print $2}' | while read f; do fp=`pwd`/$f; echo $fp; done;