linux - Bash shell - 按时间顺序统计并显示目录和子目录列表

标签 linux bash shell

给出了以目录名称开头的子树中按时间顺序(例如,按修改日期)计算和显示目录列表的 Shell 程序 预期的表单输出结果:

directory <directory name>--| <--initial directory
catalog <name>--------------|   
----------------------------| <--directories in the current directory
catalog <name>--------------|


directory <directory name>--| <--sub-directory
catalog <name>--------------|   
----------------------------| <--directories in the current directory
catalog <name>--------------|

----------------------------

and etc.

这是我找到的递归列出目录和子目录以及修改日期的脚本。但是如何按照时间顺序和嵌套层次进行排序呢?

#!/bin/bash

#script to recursively travel a dir of n levels

function traverse() {   
    for folderin $(ls "$1")
    do
        if [[ ! -f ${1}/${folder} ]]; then
        stat="$(date -r ${1}/${folder} +"%F %T")"
            echo "${1}/${folder} ${stat}"
            traverse "${1}/${folder}"
        fi
    done
}

function main() {
    traverse "$1"
}

main "$1"

非常感谢。 祝你有美好的一天。

附言类似这样的输出格式 - 按嵌套级别和时间顺序分隔:

1 level:
/dir1/
/dir2/
/dir2/

2 level:
/dir1/dir1/
/dir1/dir2/
/dir1/dir3/

/dir2/dir1/
/dir2/dir2/
/dir2/dir3/

/dir3/dir1/
/dir3/dir2/
/dir3/dir3/

3 level:
/dir1/dir1/dir1/
/dir1/dir1/dir2/
/dir1/dir1/dir3/

/dir1/dir2/dir1/
/dir1/dir2/dir2/
/dir1/dir2/dir3/

/dir1/dir3/dir1/
/dir1/dir3/dir2/
/dir1/dir3/dir3/

etc.

1 level:
/dir1/
/dir2/
/dir2/

2 level:
/dir1/dir1/
/dir1/dir2/
/dir1/dir3/

3 level:
/dir1/dir1/dir1/
/dir1/dir1/dir2/
/dir1/dir1/dir3/

2 level:
/dir2/dir1/
/dir2/dir2/
/dir2/dir3/

3 level:
/dir1/dir2/dir1/
/dir1/dir2/dir2/
/dir1/dir2/dir3/

2 level:
/dir3/dir1/
/dir3/dir2/
/dir3/dir3/

3 level:
/dir1/dir3/dir1/
/dir1/dir3/dir2/
/dir1/dir3/dir3/

etc.

不太重要,只是不要像那样混合嵌套级别:

/dir1/
/dir1/dir1/
/dir1/dir1/dir1/
/dir2/
/dir1/dir2/
/dir1/dir1/dir1/
/dir3/
/dir3/dir1/
/dir1/dir3/dir1/

最佳答案

您可以尝试使用 find 命令或 tree -d -t -f

这是我创建的临时结构(ls -R = 递归列表)

~/temp$ ls -R
.:
dir1/  dir2/  dir3/  file1

./dir1:
catalog1

./dir2:

./dir3:

现在您可以尝试使用 find 命令,如下所示:

找到 . -type d -exec ls -dlrt {}\; 获取列表
或者
找到。 -type d -exec ls -dlrt {}\; | wc --lines 获取计数

编辑 1:要仅获取顶级目录,您可以添加 -maxdepth 并迭代地为其提供深度值,例如

找到 . -maxdepth 1 -type d -exec ls -dlrt {}\; 获取列表
或者
找到。 -maxdepth 1 -type d -exec ls -dlrt {}\; | wc --lines 获取计数

-------------------------------------------- ---忽略以上内容-------------------------------------------- ------

编辑 2:

我明白了,现在我明白了你的问题..我制作了一个 bash 脚本来完成你的任务..你需要

  • 维护一个队列来存储您自己的处理顺序
  • 并使用我上面提到的 find 命令

下面是我制作的~/temp目录结构

$ ls -R temp
temp:
dir1/  dir2/  dir3/  file1

temp/dir1:
dir3/  dir4/

temp/dir1/dir3:

temp/dir1/dir4:

temp/dir2:
dir/  dir4/  dir5/  dir6/

temp/dir2/dir:
newdir/

temp/dir2/dir/newdir:

temp/dir2/dir4:

temp/dir2/dir5:

temp/dir2/dir6:

temp/dir3:

好吧,这里是 bash 脚本 .. 如果您认为评论/调试 echo 太多,请删除它们。 我试图解释脚本本身的逻辑(使用注释)。

#!/bin/bash
declare front_element="./temp"
#dir to start with
declare -a q=($(find "$front_element" -maxdepth 1 -type d -not -path "$front_element" -printf '%T@ %p\n' | sort | awk '{print $2}'))
#initial queue population
declare -a temp_arr

if [[ ${#q[@]} -eq 0 ]]; then
    printf "%s%s contains %d child directories(last modified time sort): \n" "----->" "$front_element" "${#q[@]}"
else
    printf "%s%s contains the following %d child directories(last modified time sort): \n" "----->" "$front_element" "${#q[@]}"
fi

printf "\t%s\n" "${q[@]}"

while [[ ${#q[@]} -ne 0 ]]
do
    front_element="${q[0]}"
    #Queue fetching front element
    #echo "$front_element is front_element"

    q=("${q[@]:1}")
    #actual queue dequeue operation=>reduction in size

    temp_arr=($(find "$front_element" -maxdepth 1 -type d -not -path "$front_element" -printf '%T@ %p\n' | sort | awk '{print $2}'))
    #excluding self during find using -not -path self, %Tk=last modified time printed in k format(here used @=>time in seconds since UTC/Unix Epoch Jan 1, 1970 midnight along with fractional part), %p=found path, sort=>uses last modified time to sort and it sorts alphabetically if same last modified time for >=2 directories(highly unlikely as it has fractional part too)

    if [[ ${#temp_arr[@]} -eq 0 ]]; then
        printf "%s%s contains %d child directories. \n" "----->" "$front_element" "${#temp_arr[@]}"
    else
        printf "%s%s contains the following %d child directories(last modified time sorted): \n" "----->" "$front_element" "${#temp_arr[@]}"
    fi
    #displaying the count as well

    if [[ ${#temp_arr[@]} -gt 0 ]]
    then
        printf "\t%s\n" "${temp_arr[@]}"
        echo
        for element in "${temp_arr[@]}"
        do
            q+=("$element")
        done
    fi
    #appending newly found stuff to the current queue for further processing

    #echo "${q[@]} is q at end of iteration"
    #echo "${temp_arr[@]} is temp_arr at end of iteration"
done

这是上述 bash 脚本的输出(在根目录上方的目录中运行)
对我来说,我的 $PWD/current_dir 是 ~ 即 $HOME 因为 我的临时目录在这里,即临时目录的父目录是 $HOME

PS:它没有经过全面测试。

这是您在问题编辑后在第一个结构中提到的输出方式。

$ ./script.bash 
----->./temp contains the following 3 child directories(last modified time sort): 
    ./temp/dir3
    ./temp/dir1
    ./temp/dir2
----->./temp/dir3 contains 0 child directories. 
----->./temp/dir1 contains the following 2 child directories(last modified time sorted): 
    ./temp/dir1/dir3
    ./temp/dir1/dir4

----->./temp/dir2 contains the following 4 child directories(last modified time sorted): 
    ./temp/dir2/dir4
    ./temp/dir2/dir5
    ./temp/dir2/dir6
    ./temp/dir2/dir

----->./temp/dir1/dir3 contains 0 child directories. 
----->./temp/dir1/dir4 contains 0 child directories. 
----->./temp/dir2/dir4 contains 0 child directories. 
----->./temp/dir2/dir5 contains 0 child directories. 
----->./temp/dir2/dir6 contains 0 child directories. 
----->./temp/dir2/dir contains the following 1 child directories(last modified time sorted): 
    ./temp/dir2/dir/newdir

----->./temp/dir2/dir/newdir contains 0 child directories. 

PPS:我硬编码了根目录'./temp',你需要将它更改为你的根目录

关于linux - Bash shell - 按时间顺序统计并显示目录和子目录列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35434294/

相关文章:

linux - 在 redhat 上安装 nodejs 4

regex - 如何解决这个 sed 语法问题

android - adb pull 在 bash 脚本中的奇怪行为

java - Android 如何在 ListView 中设置列表<String>

c++ - g++ 找到 -lXext 但 MinGW 找不到它,错误为 : i586-mingw32msvc/bin/ld: cannot find -lXext

objective-c - 在 Linux 机器上构建 Xcode 项目

c - 为什么非阻塞地打开命名管道会返回无效的文件描述符?

linux - 当我尝试通过 SSH 检查 Linux Live Server 上的 Sudo 版本时出错

bash - shell脚本: how to pass 2 parameters in for loop?

shell - 如何保存/记录 iex shell 的输出以获取持久的命令历史记录?