查找当前目录中按修改时间排序的文件,并将结果存储在数组中

时间:2016-12-05 19:43:04

标签: bash shell

有人可以告诉我在执行shell函数时我做错了什么?

NOTES_PATH="/home/temp"

function open_note {

    local files=()                                                          
    while IFS=  read -r -d $'\0' filename; do                                        
        files+=("$filename")                                                   
    done < <(find "$NOTES_PATH" -maxdepth 1 -type f -print0 | xargs -0 ls -t)

    echo "There is/are ${#files[@]} file(s) available"
}

即使我在/ home / temp目录中可以看到2个文本文件,我每次都会得到“有/ 0个文件可用”。

请注意我想使用while循环方法来读取文件名,而不是任何其他方式,除非我无法实现我想要做的事情。 [点数:John1024回答]

P.S。如果我从命令行运行find /home/temp -maxdepth 1 -type f -print0 | xargs -0 ls -t,我会得到预期的结果。

1 个答案:

答案 0 :(得分:3)

原始代码有几个错误:

  • xargs -0之前NUL分隔内容的优势已丢失,因为ls -t的输出未以NUL分隔。
  • 由于xargs将结果拆分为多个ls -t调用,因此仅在这些批处理中进行排序:如果有足够的文件名需要两个或多个调用,则这些调用将仅单独排序,而不是全局排序。
  • 解析ls的输出为generally error-prone

更清晰的实现(假设GNU查找和GNU排序)如下所示:

open_note() {
  local filename mtime
  local -a files=( )

  while IFS= read -r -d' ' mtime && IFS= read -r -d '' filename; do
    files+=( "$filename" )
  done < <(find "$NOTES_PATH" -maxdepth 1 -type f -printf '%T@ %P\0' | sort -z -n)
}

给出的find操作会发出以下格式的流:

<epoch time> <filename><NUL>

...然后sort对其进行排序,之后while read循环会丢弃每个字段的第一部分。

其他几点说明:

  • 不要使用function关键字;它使您的代码无意义地与POSIX sh不兼容,但(与其他更有用的基础知识不同)在兼容语法方面没有任何优势。
  • 如果您正在努力保持本地人的作用范围,请确保您获得所有 - 其中包括已循环播放的名称。