免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3759 | 回复: 7
打印 上一主题 下一主题

[文件目录] Shell版tree和de-tree [复制链接]

论坛徽章:
2
白羊座
日期:2013-11-18 19:52:42辰龙
日期:2014-09-07 07:46:06
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-12 15:51 |只看该作者 |倒序浏览
本帖最后由 damcool 于 2013-10-12 17:09 编辑

为了把导出的目录文件搞得漂亮一点,又没办法安装tree,只能用土办法。真作孽!各位高手看看还有什么可以优化的。

Tree,把文件目录导成树状结构,并作美化
  1. find . -print | awk 'NR>1{printf "%s",$0;if (system("[ -d \"" $0 "\" ]") == 0) printf "/";printf "\n"}'|LC_ALL=C sort|awk 'BEGIN{system("pwd")}{n=split($0,a,"/");for (i=2;i<n;i++) if (i<n-1 || a[n]!="") {printf "| "}; if (a[n]=="") {print "|___[D]"a[n-1]} else {print "|___[F]"a[n]}}'|tac|awk '{n=split($0,a,"");for(i=1;i<=n;i++) {if (a[i]=="|" && b[i]!="|" && a[i+1]!="_") a[i]=" "; b[i]=a[i];printf "%s",b[i]}; print ""}'|tac
复制代码
De-Tree,将导出的树状结构还原成find . -print 输出,想想真TMD觉得自己有点贱,喜欢自孽!
  1. cat /tmp/tree|awk 'NR==1{base=$0;folders="";print $0}NR>1{while (gsub(/\|  /,"| |"));sub(/___\[[D|F]\]/,"");n=split($0,a,"|");split(folders,b,"/");folders="";for(i=2;i<n;i++)folders=folders"/"b[i];folders=folders"/"a[n]; print base""folders}'
复制代码

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
2 [报告]
发表于 2013-10-14 19:12 |只看该作者
蛮好。

这里有个现成的 http://www.centerkey.com/tree/
  1. #!/bin/sh
  2. #######################################################
  3. #  UNIX TREE                                          #
  4. #  Version: 2.3                                       #
  5. #  File: ~/apps/tree/tree.sh                          #
  6. #                                                     #
  7. #  Displays Structure of Directory Hierarchy          #
  8. #  -------------------------------------------------  #
  9. #  This tiny script uses "ls", "grep", and "sed"      #
  10. #  in a single command to show the nesting of         #
  11. #  sub-directories.  The setup command for PATH       #
  12. #  works with the Bash shell (the Mac OS X default).  #
  13. #                                                     #
  14. #  Setup:                                             #
  15. #     $ cd ~/apps/tree                                #
  16. #     $ chmod u+x tree.sh                             #
  17. #     $ ln -s ~/apps/tree/tree.sh ~/bin/tree          #
  18. #     $ echo "PATH=~/bin:\${PATH}" >> ~/.profile      #
  19. #                                                     #
  20. #  Usage:                                             #
  21. #     $ tree [directory]                              #
  22. #                                                     #
  23. #  Examples:                                          #
  24. #     $ tree                                          #
  25. #     $ tree /etc/opt                                 #
  26. #     $ tree ..                                       #
  27. #                                                     #
  28. #  Public Domain Software -- Free to Use as You Like  #
  29. #  http://www.centerkey.com/tree  -  By Dem Pilafian  #
  30. #######################################################

  31. echo
  32. if [ "$1" != "" ]  #if parameter exists, use as base folder
  33.    then cd "$1"
  34.    fi
  35. pwd
  36. ls -R | grep ":$" |   \
  37.    sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
  38. # 1st sed: remove colons
  39. # 2nd sed: replace higher level folder names with dashes
  40. # 3rd sed: indent graph three spaces
  41. # 4th sed: replace first dash with a vertical bar
  42. if [ `ls -F -1 | grep "/" | wc -l` = 0 ]   # check if no folders
  43.    then echo "   -> no sub-directories"
  44.    fi
  45. echo
  46. exit
复制代码

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
3 [报告]
发表于 2013-10-14 19:16 |只看该作者
看了一下,就是一行语句
  1. ls -R | grep ":$" |sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
复制代码

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
4 [报告]
发表于 2013-10-14 19:40 |只看该作者
本帖最后由 rdcwayx 于 2013-10-14 21:57 编辑

http://en.wikipedia.org/wiki/Tree_(Unix)
  1. find . -type d
  2. # or
  3. ls -R | grep ': | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/'
  4. # or
  5. ls -R | grep ': | sed -e 's/:$//' -e 's/[^\/]*\//|  /g' -e 's/|  \([^|]\)/`--\1/g'
  6. # or
  7. find . -print | sort | sed 's;[^/]*/;|___;g;s;___|; |;g'
复制代码
命令 tree 的 源代码, 自己可以编译的。
ftp://mama.indstate.edu/linux/tree/
tree-1.6.0.tar (160 KB, 下载次数: 13)

论坛徽章:
2
白羊座
日期:2013-11-18 19:52:42辰龙
日期:2014-09-07 07:46:06
5 [报告]
发表于 2013-10-14 20:06 |只看该作者
rdcwayx 发表于 2013-10-14 19:40
http://en.wikipedia.org/wiki/Tree_(Unix)命令 tree 的 源代码, 自己可以编译的。
ftp://mama.indstate. ...


很不错的资料,运行起来出结果也很快。不过不能区分文件或目录,而且对树状结构的处理也很粗糙。

论坛徽章:
15
2015年辞旧岁徽章
日期:2015-03-03 16:54:15双鱼座
日期:2015-01-15 17:29:44午马
日期:2015-01-06 17:06:51子鼠
日期:2014-11-24 10:11:13寅虎
日期:2014-08-18 07:10:55酉鸡
日期:2014-04-02 12:24:51双子座
日期:2014-04-02 12:19:44天秤座
日期:2014-03-17 11:43:36亥猪
日期:2014-03-13 08:13:51未羊
日期:2014-03-11 12:42:03白羊座
日期:2013-11-20 10:15:18CU大牛徽章
日期:2013-04-17 11:48:45
6 [报告]
发表于 2013-10-15 08:52 |只看该作者
毕竟方便而且速度快很多啊, 自己设个alias 就可以直接用了。
  1. alias tree="ls -R | grep ":$" |sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/   /' -e 's/-/|/' "
复制代码
如果要分辨目录和文件,可以用这个:
  1. find . -exec ls -Fd {} \; | sort |sed 's;\/$;[d];; s;[^/]*/;|___;g;s;___|; |;g'
复制代码

论坛徽章:
2
白羊座
日期:2013-11-18 19:52:42辰龙
日期:2014-09-07 07:46:06
7 [报告]
发表于 2013-10-15 09:34 |只看该作者
本帖最后由 damcool 于 2013-10-24 17:10 编辑

来个完整的tree.sh吧
  1. #!/bin/bash

  2. ################################################################################
  3. #  Function Name:    HELP_USAGE
  4. #  Description:      Function to display the usage of the script
  5. #  Parameters:       None
  6. #  Return:           Help messages
  7. #  Called By:        Script Main Loop->Script Parameters' Handler
  8. #  History:          2013-Oct-15    Initial Edition              RobinHoo
  9. ################################################################################
  10. function help_usage(){
  11. cat <<EOF
  12. Usage: $PROGNAME [OPTION]... [DIRECTORY_NAME]
  13. Display directories and/or files in tree view instead of binary tree command.

  14.   -d, --dir      Display only the director tree
  15.   -r, --reverse  De-Tree of the directory tree view to find . -print layout
  16.   -h, --help     Show current help message of the script usages
  17.   
  18.   
  19. Example:
  20.   $PROGNAME              Display the tree view from current folder
  21.   $PROGNAME --dir        Display the directory tree view from current folder
  22.   $PROGNAME -d /usr      Show the directory tree view for /usr
  23.   $PROGNAME /etc         Show the tree view of /etc with files listed
  24.   
  25. Please Report Script Bugs to $AUTHOR_MAIL


  26. EOF
  27. exit 1
  28. }

  29. ################################################################################
  30. #  Function Name:    DUMP_FOLDER
  31. #  Description:      Function to display the tree view of given folder
  32. #  Parameters:       Folder Name,Prefix Tree
  33. #  Return:           None
  34. #  Called By:        Script Main Loop->Folder Tree View Drawing
  35. #  History:          2013-Oct-15    Initial Edition              RobinHoo
  36. ################################################################################
  37. function dump_folder(){
  38.     local dir_name="$1"
  39.     local dir_tree="$2"
  40.     local dir_item=""
  41.     local dir_nbr=0
  42.     local dir_idx=2
  43.     local dir_ifs=$IFS
  44.     IFS=\n'
  45.     if [ $FOLDER -eq 0 ]; then
  46.         dir_nbr=$(find "$dir_name" -maxdepth 1 -print|wc -l)
  47.         for dir_item in $(find "$dir_name" -maxdepth 1 -print|awk 'NR>1{n=split($0,a,"/");if (system("[ -d \"" $0 "\" ]") == 0) {printf "[D]"} else printf "[F]"; printf "%s\n",a[n]}'|sort); do
  48.             echo "$dir_tree|___$dir_item"
  49.             [ "$dir_name" == "/" ] && dir_name=""
  50.             if [ "${dir_item:0:3}" == "[D]" ] ; then
  51.                 dir_item="${dir_item:3}"
  52.                 [ $dir_idx -eq $dir_nbr ] && dump_folder "$dir_name/$dir_item" "$dir_tree  " || dump_folder "$dir_name/$dir_item" "$dir_tree| "
  53.             fi
  54.             dir_idx=$(($dir_idx+1))
  55.         done;
  56.     else
  57.         dir_nbr=$(find "$dir_name" -maxdepth 1 -type d -print|wc -l)
  58.         for dir_item in $(find "$dir_name" -maxdepth 1 -type d -print|awk 'NR>1{n=split($0,a,"/");printf "[D]%s\n",a[n]}'|sort); do
  59.             echo "$dir_tree|___$dir_item"
  60.             [ "$dir_name" == "/" ] && dir_name=""
  61.             dir_item="${dir_item:3}"
  62.             [ $dir_idx -eq $dir_nbr ] && dump_folder "$dir_name/$dir_item" "$dir_tree  " || dump_folder "$dir_name/$dir_item" "$dir_tree| "
  63.             dir_idx=$(($dir_idx+1))
  64.         done;   
  65.     fi
  66.     IFS=$dir_ifs
  67. }



  68. ################################################################################
  69. #  Function Name:    Script Main Loop
  70. #  History:          2012-Jun-06    Initial Edition              RobinHoo
  71. ################################################################################
  72. TREE_DIR="$(pwd)"
  73. BASE_DIR=$(cd "$(dirname "$0")" && pwd)
  74. PROGNAME=$(basename "$0")
  75. AUTHOR_MAIL="robin.hoo(at)outlook.com"
  76. FOLDER=0
  77. HELP=0
  78. REVERSE=0
  79. while [ $# -gt 0 ]
  80. do
  81.     case "$1" in
  82.     (-d)            FOLDER=1;;
  83.     (-r)            REVERSE=1;TREE_DIR="/dev/stdin";;
  84.     (-h)            HELP=1;shift;break;;
  85.     (--dir)         FOLDER=1;;
  86.     (--reverse)     REVERSE=1;TREE_DIR="/dev/stdin";;
  87.     (--help)        HELP=1;shift;break;;
  88.     (-*)            echo "$PROGNAME: error - unrecognized option or parameter $1" 1>&2; HELP=1;break;;
  89.     (*)             TREE_DIR="$1";shift;break;;
  90.     esac
  91.     shift
  92. done
  93. [ $# -gt 0 ] && HELP=1
  94. [ $REVERSE -eq 0 ] && [ ! -d "$TREE_DIR" ] && HELP=1
  95. [ $REVERSE -eq 1 ] && [ "$TREE_DIR" != "/dev/stdin" ] && [ ! -f "$TREE_DIR" ] && HELP=1
  96. [ $HELP -eq 1 ] && help_usage

  97. [ $REVERSE -eq 0 ] && echo "$TREE_DIR" && dump_folder "$TREE_DIR" ""
  98. [ $REVERSE -eq 1 ] && cat <"$TREE_DIR"|awk 'NR==1{if ($0!="/") base=$0;folders="";print base"/"}NR>1{gsub(/^   /,"  |");while (gsub(/\|  /,"| |"));if (gsub(/___\[D\]/,"___[D]")) $0=$0"/";sub(/___\[[D|F]\]/,"");n=split($0,a,"|");split(folders,b,"/");folders="";for(i=2;i<n;i++)folders=folders"/"b[i];folders=folders"/"a[n]; print base""folders}'
复制代码

论坛徽章:
2
白羊座
日期:2013-11-18 19:52:42辰龙
日期:2014-09-07 07:46:06
8 [报告]
发表于 2013-10-15 10:14 |只看该作者
rdcwayx 发表于 2013-10-15 08:52
毕竟方便而且速度快很多啊, 自己设个alias 就可以直接用了。如果要分辨目录和文件,可以用这个:


嗯,我最早也是用你列出的办法,不过,本人有点吹毛求疵,最后忍不住自己写了一个。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP