【问题标题】:Shell script to recursively print full directory tree using ls使用 ls 递归打印完整目录树的 Shell 脚本
【发布时间】:2017-04-25 22:13:23
【问题描述】:

作业:我必须使用 diff 和 sort 创建一个 shell 脚本,并使用 ls -l、grep '^d' 和 awk '{print $9}' 创建一个管道来打印完整的目录树。

我编写了一个 C 程序来显示我要查找的内容。这是输出:

ryan@chrx:~/Documents/OS-Projects/Project5_DirectoryTree$ ./a.out 
TestRoot/
[Folder1]
  [FolderC]
  [FolderB]
  [FolderA]
[Folder2]
  [FolderD]
  [FolderF]
  [FolderE]
[Folder3]
  [FolderI]
  [FolderG]
  [FolderH]

到目前为止我写了这个:

ls -R -l $1 | grep '^d' | awk '{print $9}' 

要打印目录树,但现在我需要一种按文件夹深度和可能缩进但不是必需的方式对其进行排序。有什么建议么?我不能使用 find 或 tree 命令。

编辑:最初的分配和限制是错误的,并在以后更改。如果您无视限制,当前的答案是很好的解决方案,因此请将它们留给任何有类似问题的人。至于新任务,以防有人想知道。我要递归打印所有子目录,对它们进行排序,然后将它们与我的程序进行比较,以确保它们具有相似的结果。这是我的解决方案:

#!/bin/bash
echo Program:
./a.out $1 | sort
echo Shell Script:
ls -R -l $1 | grep '^d' | awk '{print $9}' | sort

diff <(./a.out $1 | sort) <(ls -R -l $1 | grep '^d' | awk '{print $9}' | sort)
DIFF=$?

if [[ $DIFF -eq 0 ]]
then
    echo "The outputs are similar!"
fi

【问题讨论】:

  • 当你使用 awk 时,你永远不需要 grep,因为 awk 可以做任何 grep 可以做的有用的事情(例如 grep '^d' | awk '{print $9}' = awk '/^d/{print $9}'),递归查找目录的工具是 find -type d,不是ls -R,这和 diff 或 sort 有什么关系?
  • 我明白这一点。限制、差异和排序只是给定任务的一部分。如果可以的话,我会以不同的方式编写脚本。
  • 但是你会区分什么,例如?您可以在脚本中的某处输入diff /etc/password /dev/null &gt; /dev/null 以使用diff,我怀疑您是否会为此获得任何分数,但我无法想象您会在这个问题中使用 diff 做什么。
  • 我知道是对的。即使对我来说,我的教授对此的描述也毫无意义。这就是我在这里问的原因。不过,我正在考虑反对这篇论文。至少我知道我没疯。
  • 该脚本需要单行吗?

标签: linux bash shell awk grep


【解决方案1】:

您不需要 lsgrepawk 来获取树。简单递归 bash 函数将是足够的,例如:

#!/bin/bash
walk() {
        local indent="${2:-0}"
        printf "%*s%s\n" $indent '' "$1"
        for entry in "$1"/*; do
                [[ -d "$entry" ]] && walk "$entry" $((indent+4))
        done
}
walk "$1"

如果你以bash script.sh /etc 运行它,它会打印如下目录树:

/etc
    /etc/apache2
        /etc/apache2/extra
        /etc/apache2/original
            /etc/apache2/original/extra
        /etc/apache2/other
        /etc/apache2/users
    /etc/asl
    /etc/cups
        /etc/cups/certs
        /etc/cups/interfaces
        /etc/cups/ppd
    /etc/defaults
    /etc/emond.d
        /etc/emond.d/rules
    /etc/mach_init.d
    /etc/mach_init_per_login_session.d
    /etc/mach_init_per_user.d
    /etc/manpaths.d
    /etc/newsyslog.d
    /etc/openldap
        /etc/openldap/schema
    /etc/pam.d
    /etc/paths.d
    /etc/periodic
        /etc/periodic/daily
        /etc/periodic/monthly
        /etc/periodic/weekly
    /etc/pf.anchors
    /etc/postfix
        /etc/postfix/postfix-files.d
    /etc/ppp
    /etc/racoon
    /etc/security
    /etc/snmp
    /etc/ssh
    /etc/ssl
        /etc/ssl/certs
    /etc/sudoers.d

【讨论】:

  • 你的解决方案很酷,但是原帖提出了 我必须使用 diff 和 sort 创建一个 shell 脚本,以及使用 ls -l, grep '^d 创建一个管道',然后 awk '{print $9}' 打印完整的目录树。
  • @RogerSinasohn ,如果您无视限制,这是关于原始问题的一个很好的解决方案。我添加了一个编辑,说明分配的描述不正确,并添加了我的解决方案。
【解决方案2】:

借鉴@jm666 在 /etc 上运行它的想法:

$ find /etc -type d -print | awk -F'/' '{printf "%*s[%s]\n", 4*(NF-2), "", $0}'
[/etc]
    [/etc/alternatives]
    [/etc/bash_completion.d]
    [/etc/defaults]
        [/etc/defaults/etc]
            [/etc/defaults/etc/pki]
                [/etc/defaults/etc/pki/ca-trust]
                [/etc/defaults/etc/pki/nssdb]
            [/etc/defaults/etc/profile.d]
            [/etc/defaults/etc/skel]
    [/etc/fonts]
        [/etc/fonts/conf.d]
    [/etc/fstab.d]
    [/etc/ImageMagick]
    [/etc/ImageMagick-6]
    [/etc/pango]
    [/etc/pkcs11]
    [/etc/pki]
        [/etc/pki/ca-trust]
            [/etc/pki/ca-trust/extracted]
                [/etc/pki/ca-trust/extracted/java]
                [/etc/pki/ca-trust/extracted/openssl]
                [/etc/pki/ca-trust/extracted/pem]
            [/etc/pki/ca-trust/source]
                [/etc/pki/ca-trust/source/anchors]
                [/etc/pki/ca-trust/source/blacklist]
        [/etc/pki/nssdb]
        [/etc/pki/tls]
    [/etc/postinstall]
    [/etc/preremove]
    [/etc/profile.d]
    [/etc/sasl2]
    [/etc/setup]
    [/etc/skel]
    [/etc/ssl]
    [/etc/texmf]
        [/etc/texmf/tlmgr]
        [/etc/texmf/web2c]
    [/etc/xml]

抱歉,我找不到使用您提到的其他工具的明智方法,因此它可能对您没有帮助,但也许可以帮助其他人解决同样的问题,但无需使用特定工具。

【讨论】:

  • 同意。还是有用的!谢谢
猜你喜欢
  • 2016-07-22
  • 1970-01-01
  • 2022-01-25
  • 2014-08-27
  • 1970-01-01
  • 1970-01-01
  • 2015-03-01
  • 2013-07-08
  • 1970-01-01
相关资源
最近更新 更多