用于迭代文件和目录的Shell脚本

时间:2017-07-18 21:58:35

标签: bash shell

我有一个包含由日期标记的子目录的目录。这些子目录中的每一个都包含由小时标记的文件

parent_dir\
--2017-07-12\
  -2017-07-12-00 
  -2017-07-12-01
  -2017-07-12-02
  -2017-07-12-03
  ...
  -2017-07-12-23
--2017-07-13\
  -2017-07-13-00 
  -2017-07-13-01
  -2017-07-13-02
  -2017-07-13-03
  ...
  -2017-07-13-23
--2017-07-14
...

我想搜索从最新文件开始到最少的特定字符串。

我尝试了以下代码片段来遍历目录:

MAIN_DIR="/<main_dir_location>"
for directory in `$MAIN_DIR/* | sort -r`; do
    echo "$directory"
done

MAIN_DIR="/<main_dir_location>" 
for directory in $("$MAIN_DIR"/* | sort -r); do
    echo "$directory"
done

我收到错误

/<main_dir_location>/2017-07-12: is a directory

对我而言,shell看起来正在尝试执行从for循环中获取的目录值。

  • 这种理解是否正确?
  • 我该如何解决这个问题?
  • 有没有更好的方法来完成我在这里尝试做的事情?

2 个答案:

答案 0 :(得分:1)

你必须做

for directory in $( ls -d "$MAIN_DIR" | sort -r); do

您的命令尝试将目录名称用作命令。

ls -d列出$MAIN_DIR下的所有目录并将其传递给sort -r

<强> BUT

您可以使用查找并按日期修改(或类似)对答案进行排序:

find $MAIN_DIR -type d -maxdepth 1 -printf "%T+\t%p\n" | sort

-type d只有目录

-maxdepth 1深入一个文件夹

如果你愿意,你甚至可以通过正则表达式和更复杂的操作进行过滤,例如&#34;比文件&#34更新... ..

有关查找选项和查找printf选项,请参阅find's manpage

答案 1 :(得分:1)

"$MAIN_DIR"/* 扩展(除非目录为空)到目录列表。您将此扩展放置在预期命令的位置,并将第一个展开的项目作为可执行文件进行尝试。

如果您在扩展名前加上

printf '%s\n' #prints each argument on a line

脚本可以正常工作(只要你不在文件名中包含空格/字符串):

MAIN_DIR="/<main_dir_location>" 
for directory in $(prinf '%s\n' "$MAIN_DIR"/* | sort -r); do
    echo "$directory"
done

如果你想消除全局字符和大多数空格的问题(换行仍然是不行),你可以这样做:

printf  '%s\n' "$MAIN_DIR"/* | sort -r | while read -r directory; do
     #...
done