通过文件名列表,以便他们迭代在bash创建 [英] Iterate through list of filenames in order they were created in bash

查看:141
本文介绍了通过文件名列表,以便他们迭代在bash创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

解析 LS的输出通过的文件列表进行迭代是 。所以,我应该如何去通过的文件列表,以便进行迭代由他们首先创造出来的?我在这里浏览几个问题上的SO,他们似乎都解析 LS

嵌入的链接提示:


  

事情变得更加困难,如果你想一些具体的分选
  仅 LS 可以做,如的mtime 排序。如果你想最老的或
  目录中最新的文件,不要使用 LS -t |头-1 - 阅读常见问题猛砸
  99来代替。 如果你真的需要在目录中的所有文件的列表
  为了通过的mtime,这样就可以按顺序处理它们,切换到
  Perl和有你的Perl程序做它自己的目录开
  排序。然后做处理Perl程序,或者 - 最坏的情况下
  场景 - 有perl程序吐出文件名以NUL
  分隔符。


  
  

更妙的是,把修改时间的文件名,在年月日
  格式,以便水珠顺序也修改时间顺序。然后,你不需要LS
  或Perl或任何东西。 (绝大多数情况下,人们希望
  目录中的最古老的或最新的文件可以直接通过做来解决
  这一点)。


这是否意味着有本机在庆典做这件事的方式是什么?我没有自由修改文件名,包括在他们的时间。我需要安排在的cron 的脚本,将运行每5分钟,生成包含在其创建时间排序特定目录下的所有文件的数组并执行的一些行动文件名和它们移动到另一个位置。

下面的工作,但只是因为我别有风趣的文件名。该文件由服务器创建,因此永远不会有特殊字符,空格,换行等。

 文件=($(LS -1tr))

我可以写一个 perl的脚本,该脚本会做什么,我需要,但我会AP preciate如果有人可以建议做它在<$ C的正确方法$ C>庆典。便携式的选择是伟大的,但使用的解决方案最新的GNU工具会不会是问题。


解决方案

  sorthelper =();
在*文件;做
    #我们需要的东西,可以很容易地进行排序。
    #在这里,我们用&LT;日期和GT;&LT;&名GT;。
    #注意这与在文件名中的任何特殊字符    sorthelper + =($(STAT -n -f%钐%N-t%Y%M%D%H%M%S - $文件));只有#的Mac OS X
    # 要么
    sorthelper + =($(统计--printf%Y%N - $文件));唯一的Linux#
完成的;排序=();
而读-d $'\\ 0'ELEM;做
    #这个除掉的前14个字符(小于日期&GT;)
    分类+ =($ {ELEM:14});
完成&LT; ≤(printf的'%S \\ 0'$ {sorthelper [@]}|排序-z)在文件$ {分类[@]};做
    #做你的东西...
    回声$文件;
完成的;

除了排序统计,所有的命令都是实际的本机猛砸命令(内建)*。如果你真的想要,可以实现自己的排序使用bash内建命令只的,但我看到没有摆脱与stat方式。

重要的部分是读-d $'\\ 0'的printf'%s的\\ 0'排序-z 。所有这些命令与它们空定界符选项使用,这意味着,任何文件名可以安全procesed。此外,在使用双引号的$文件$ {anarray [*]}是是必不可少的。

* <子>很多人都觉得GNU工具都弄好猛砸的一部分,但在技术上他们没有。因此,统计排序是一样的非本地为 perl的

Parsing output of ls to iterate through list of files is bad. So how should I go about iterating through list of files in order by which they were first created? I browsed several questions here on SO and they all seem to parsing ls.

The embedded link suggests:

Things get more difficult if you wanted some specific sorting that only ls can do, such as ordering by mtime. If you want the oldest or newest file in a directory, don't use ls -t | head -1 -- read Bash FAQ 99 instead. If you truly need a list of all the files in a directory in order by mtime so that you can process them in sequence, switch to perl, and have your perl program do its own directory opening and sorting. Then do the processing in the perl program, or -- worst case scenario -- have the perl program spit out the filenames with NUL delimiters.

Even better, put the modification time in the filename, in YYYYMMDD format, so that glob order is also mtime order. Then you don't need ls or perl or anything. (The vast majority of cases where people want the oldest or newest file in a directory can be solved just by doing this.)

Does that mean there is no native way of doing it in bash? I don't have the liberty to modify the filename to include the time in them. I need to schedule a script in cron that would run every 5 minutes, generate an array containing all the files in a particular directory ordered by their creation time and perform some actions on the filenames and move them to another location.

The following worked but only because I don't have funny filenames. The files are created by a server so it will never have special characters, spaces, newlines etc.

files=( $(ls -1tr) ) 

I can write a perl script that would do what I need but I would appreciate if someone can suggest the right way to do it in bash. Portable option would be great but solution using latest GNU utilities will not be a problem either.

解决方案

sorthelper=();
for file in *; do
    # We need something that can easily be sorted.
    # Here, we use "<date><filename>".
    # Note that this works with any special characters in filenames

    sorthelper+=("$(stat -n -f "%Sm%N" -t "%Y%m%d%H%M%S" -- "$file")"); # Mac OS X only
    # or
    sorthelper+=("$(stat --printf "%Y    %n" -- "$file")"); # Linux only
done;

sorted=();
while read -d $'\0' elem; do
    # this strips away the first 14 characters (<date>) 
    sorted+=("${elem:14}");
done < <(printf '%s\0' "${sorthelper[@]}" | sort -z)

for file in "${sorted[@]}"; do
    # do your stuff...
    echo "$file";
done;

Other than sort and stat, all commands are actual native Bash commands (builtins)*. If you really want, you can implement your own sort using Bash builtins only, but I see no way of getting rid of stat.

The important parts are read -d $'\0', printf '%s\0' and sort -z. All these commands are used with their null-delimiter options, which means that any filename can be procesed safely. Also, the use of double-quotes in "$file" and "${anarray[*]}" is essential.

*Many people feel that the GNU tools are somehow part of Bash, but technically they're not. So, stat and sort are just as non-native as perl.

这篇关于通过文件名列表,以便他们迭代在bash创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆