292

Существует ли эквивалент команды Ubuntu tree для Mac OS X?

13 ответов13

408

Вы также можете получить команду tree на macOS. Если у вас есть Homebrew, все, что вам нужно сделать, это запустить:

brew install tree

Читайте дальше для деталей.


С менеджером пакетов

Есть несколько менеджеров пакетов для macOS. Наиболее популярными являются: Homebrew, MacPorts или Fink. Вы можете установить любой из них, но я рекомендую Homebrew. Не устанавливайте более одного из них одновременно!

Следуйте инструкциям на веб-сайте, затем выполните одну из следующих команд, в зависимости от того, какой менеджер пакетов вы выбрали.

Для доморощенного:

brew install tree

Для MacPorts:

sudo port install tree

Для Финка:

fink install tree

Менеджеры пакетов предлагают другие программы командной строки, включая GNU/Linux, которые по умолчанию не поставляются с macOS.

Установка из источника

Сначала вы должны установить инструменты командной строки Xcode, выполнив xcode-select --install .

Затем загрузите исходный код tree. Затем измените Makefile, чтобы он заработал, что также объясняется в ответе @ apuche ниже. Достаточно закомментировать опции Linux и раскомментировать опции macOS.

Затем запустите ./configure , затем make .

Теперь вам нужно переместить двоичный файл tree в место, которое находится в вашем пути к исполняемому файлу. Например:

sudo mkdir -p /usr/local/bin
sudo cp tree /usr/local/bin/tree

Теперь отредактируйте ваш ~/.bash_profile включив в него:

export PATH="/usr/local/bin:$PATH"

Перезагрузите оболочку, и теперь, which tree должно указывать на /usr/local/bin/tree .

29

Не совсем то же самое, но один быстрый способ на Mac:

find .

и это все. Он перечислит все пути к файлам в текущем каталоге в виде списка.

21

Вы, вероятно, должны использовать доморощенный. Если вы делаете:

brew install tree
19

Или, если ваш администратор не позволит вам установить какой-либо из инструментов brew , fink , port , вы всегда можете собрать его из исходного кода:

curl -O ftp://mama.indstate.edu/linux/tree/tree-1.5.3.tgz
tar xzvf tree-1.5.3.tgz
cd tree-1.5.3/
ls -al

Отредактируйте Makefile, чтобы прокомментировать часть linux и раскомментировать область osx:

# Linux defaults:
#CFLAGS=-ggdb -Wall -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
#CFLAGS=-O2 -Wall -fomit-frame-pointer -DLINUX -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
#LDFLAGS=-s

# Uncomment for OS X:
CC=cc
CFLAGS=-O2 -Wall -fomit-frame-pointer -no-cpp-precomp
LDFLAGS=
XOBJS=strverscmp.o

Необязательно: принудительный вывод цвета

И пока вы это делаете, если вы хотите, чтобы дерево всегда раскрашивало вывод, вы всегда можете отредактировать main метод файла tree.c и добавить force_color=TRUE; перед setLocale(LC_TYPE,"");

Наконец нажмите make и вы закончили сборку tree для Mac.

Дань идет к Шону Чепмену за его оригинальный пост в своем блоге.

18

По сути, нет формальной команды tree но вы можете сделать это:

Сохраните следующий скрипт в /usr /local /bin /tree

#!/bin/bash

SEDMAGIC='s;[^/]*/;|____;g;s;____|; |;g'

if [ "$#" -gt 0 ] ; then
   dirlist="$@"
else
   dirlist="."
fi

for x in $dirlist; do
     find "$x" -print | sed -e "$SEDMAGIC"
done

Измените разрешения, чтобы вы могли запустить его:

chmod 755 /usr/local/bin/tree 

Конечно, вам может понадобиться создать /usr/local/bin:

sudo mkdir -p /usr/local/bin/tree 
5

Альтернатива с использованием find и awk:

#!/bin/bash
find . -print 2>/dev/null | awk '!/\.$/ { \
    for (i=1; i<NF; i++) { \
        printf("%4s", "|") \
    } \
    print "-- "$NF \
}' FS='/'
3

Я нашел простое решение здесь: http://murphymac.com/tree-command-for-mac/

Поэтому добавление следующего в ваш .bashrc , .bash_profile или любое другое место заставит его работать:

alias tree="find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'"

Теперь добавление команды tree будет выглядеть так:

# ~/my-html-app [13:03:45]$ tree
.
|____app.js
|____css
| |____main.css
| |____theme.css
|____index.html
3

Добавление небольшого пункта к ответу @ apuche для функции без корневого доступа OSX El Capitan. Сбой make install поскольку нам не разрешено записывать в каталог /usr/bin .

vikas@MBP:~/Downloads/tree-1.7.0$ sudo make install
Password:
install -d /usr/bin
install: chmod 755 /usr/bin: Operation not permitted
install -d /usr/share/man/man1
if [ -e tree ]; then \
        install tree /usr/bin/tree; \
    fi
install: /usr/bin/tree: Operation not permitted
make: *** [install] Error 71
vikas@MBP:~/Downloads/tree-1.7.0$

Чтобы преодолеть это, просто отредактируйте Makefile чтобы иметь prefix = /usr/local

2

Я добавил следующее в ~/.bash_profile для использования в Terminal.app. Некоторые комментарии включены, чтобы помочь вспомнить, как используется find.

##########
## tree ##
##########
## example ...
#|____Cycles
#| |____.DS_Store
#| |____CyclesCards.json
#| |____Carbon
#| | |____Carbon.json
# alternate: alias tree='find . -print | sed -e "s;[^/]*/;|____;g;s;____|; |;g"'
# use$ tree ; tree . ; tree [some-folder-path]
function tree {
    find ${1:-.} -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
}

пример для текущего каталога

$> tree

пример для некоторого пути

$> tree /some/path
2

Вот сценарий Ruby, который создает красивое дерево Unicode вместе с полезными метаданными.

#!/usr/bin/env ruby
def tree_hierarchy( root, &children )
  queue = [[root,"",true]]
  [].tap do |results|
    until queue.empty?
      item,indent,last = queue.pop
      kids = children[item]
      extra = indent.empty? ? '' : last ? '└╴' : '├╴'
      results << [ indent+extra, item ]
      results << [ indent, nil ] if last and kids.empty?
      indent += last ? '  ' : '│ '
      parts = kids.map{ |k| [k,indent,false] }.reverse
      parts.first[2] = true unless parts.empty?
      queue.concat parts
    end
  end
end
def tree(dir)
  cols = tree_hierarchy(File.expand_path(dir)) do |d|
    File.directory?(d) ? Dir.chdir(d){ Dir['*'].map(&File.method(:expand_path)) } : []
  end.map do |indent,path|
    if path
      file = File.basename(path) + File.directory?(path) ? '/' : ''
      meta = `ls -lhd "#{path}"`.split(/\s+/)
      [ [indent,file].join, meta[0], meta[4], "%s %-2s %s" % meta[5..7] ]
    else
      [indent]
    end
  end
  maxs = cols.first.zip(*(cols[1..-1])).map{ |c| c.compact.map(&:length).max }
  tmpl = maxs.map.with_index{ |n,i| "%#{'-' if cols[0][i][/^\D/]}#{n}s" }.join('  ')
  cols.map{ |a| a.length==1 ? a.first : tmpl % a }
end
puts tree(ARGV.first || ".") if __FILE__==$0

Вы можете изменить строку meta = … для извлечения различных метаданных для отображения, выбирая вручную разделенные фрагменты на следующей строке. Еще немного поработав, вы можете передать произвольные аргументы ls, чтобы выбрать метаданные для отображения.

Пример вывода (выглядит лучше в терминале OS X, чем шрифт в переполнении стека):

phrogz$ tree UCC_IVI/
UCC_IVI/                               drwxr-xr-x  510B  Nov 20 11:07
  ├╴docs/                              drwxr-xr-x  102B  Nov 20 19:21
  │ └╴CANMessages.txt                  -rwxr-xr-x  2.2K  Nov 20 19:21
  │ 
  ├╴effects/                           drwxr-xr-x  204B  Nov 19 17:19
  │ ├╴Depth Of Field HQ Blur.effect    -rwxr-xr-x  2.4K  Nov 19 17:19
  │ ├╴FXAA.effect                      -rwxr-xr-x  1.6K  Nov 17 15:38
  │ ├╴HDRBloomTonemap.effect           -rwxr-xr-x   11K  Nov 17 15:38
  │ └╴SMAA1X.effect                    -rwxr-xr-x  4.4K  Nov 19 17:19
  │ 
  ├╴fonts/                             drwxr-xr-x  136B  Nov 17 15:38
  │ ├╴Arimo-Regular.ttf                -rwxr-xr-x   43K  Nov 17 15:38
  │ └╴OFL.txt                          -rwxr-xr-x  4.3K  Nov 17 15:38
  │ 
  ├╴maps/                              drwxr-xr-x  238B  Nov 19 17:19
  │ ├╴alpha-maps/                      drwxr-xr-x  136B  Nov 17 15:38
  │ │ ├╴rounded-boxes-3.png            -rwxr-xr-x  3.6K  Nov 17 15:38
  │ │ └╴splatter-1.png                 -rwxr-xr-x   35K  Nov 17 15:38
  │ │ 
  │ ├╴effects/                         drwxr-xr-x  136B  Nov 19 17:19
  │ │ ├╴AreaTex-yflipped.dds           -rwxr-xr-x  175K  Nov 19 17:19
  │ │ └╴SearchTex-yflipped.png         -rwxr-xr-x  180B  Nov 19 17:19
  │ │ 
  │ ├╴IBL/                             drwxr-xr-x  136B  Nov 17 15:38
  │ │ ├╴028-hangar.hdr                 -rwxr-xr-x  1.5M  Nov 17 15:38
  │ │ └╴FieldAirport.hdr               -rwxr-xr-x  1.5M  Nov 17 15:38
  │ │ 
  │ ├╴icons/                           drwxr-xr-x  238B  Nov 19 17:19
  │ │ ├╴icon_climate.dds               -rwxr-xr-x  683K  Nov 19 17:19
  │ │ ├╴icon_music.dds                 -rwxr-xr-x  683K  Nov 19 17:19
  │ │ ├╴icon_navigation.dds            -rwxr-xr-x  683K  Nov 19 17:19
  │ │ ├╴icon_phone.dds                 -rwxr-xr-x  683K  Nov 19 17:19
  │ │ └╴icon_surroundView.dds          -rwxr-xr-x  683K  Nov 19 17:19
  │ │ 
  │ └╴materials/                       drwxr-xr-x  102B  Nov 19 17:19
  │   └╴spherical_checker.png          -rwxr-xr-x   11K  Nov 19 17:19
  │   
  ├╴materials/                         drwxr-xr-x  102B  Nov 19 17:19
  │ └╴thin_glass_refractive.material   -rwxr-xr-x  6.0K  Nov 19 17:19
  │ 
  ├╴models/                            drwxr-xr-x  136B  Nov 19 17:19
  │ ├╴BokehParticle/                   drwxr-xr-x  136B  Nov 19 17:19
  │ │ ├╴BokehParticle.import           -rwxr-xr-x  739B  Nov 19 17:19
  │ │ └╴meshes/                        drwxr-xr-x  102B  Nov 19 17:19
  │ │   └╴Mesh.mesh                    -rwxr-xr-x  1.1K  Nov 19 17:19
  │ │   
  │ └╴Glass_Button/                    drwxr-xr-x  136B  Nov 19 17:19
  │   ├╴Glass_Button.import            -rwxr-xr-x  1.2K  Nov 19 17:19
  │   └╴meshes/                        drwxr-xr-x  136B  Nov 19 17:19
  │     ├╴GlassButton.mesh             -rwxr-xr-x   44K  Nov 19 17:19
  │     └╴Icon.mesh                    -rwxr-xr-x  1.8K  Nov 19 17:19
  │     
  ├╴scripts/                           drwxr-xr-x  204B  Nov 19 17:19
  │ ├╴App.lua                          -rwxr-xr-x  764B  Nov 17 15:38
  │ ├╴CANSim.lua                       -rwxr-xr-x   29K  Nov 17 15:38
  │ ├╴ObjectWiggler.lua                -rwxr-xr-x  3.7K  Nov 19 17:19
  │ └╴PathWiggler.lua                  -rwxr-xr-x  2.9K  Nov 17 15:38
  │ 
  ├╴states/                            drwxr-xr-x  170B  Nov 19 18:45
  │ ├╴app-camera.scxml                 -rwxr-xr-x  2.4K  Nov 20 11:07
  │ ├╴app-navigation.scxml             -rwxr-xr-x  590B  Nov 19 18:32
  │ └╴logic.scxml                      -rwxr-xr-x  4.2K  Nov 19 18:59
  │ 
  ├╴tests/                             drwxr-xr-x  102B  Nov 17 15:38
  │ └╴interface-navigation.scxml-test  -rwxr-xr-x   83B  Nov 17 15:38
  │ 
  ├╴UCC_IVI.uia                        -rwxr-xr-x  630B  Nov 19 17:32
  ├╴UCC_IVI.uia-user                   -rwxr-xr-x  832B  Nov 20 17:22
  ├╴UCC_IVI.uip                        -rwxr-xr-x  1.5K  Nov 17 15:38
  └╴UCC_Menu.uip                       -rwxr-xr-x   33K  Nov 19 17:19
1

Это не так красиво, как gnu tree ... но в bash очень просто использовать псевдонимы ... Вы даже можете добавить немного цвета, добавив опцию G в цвет ls osx.

alias tree='find . -type d | ls -lARG'
0

Поздно к игре, но у меня был тот же вопрос. Из-за ограничений на рабочем месте я не смог установить пакет из исходного кода или через сторонний менеджер пакетов.

Это моя реализация:

# Faux tree command in OS X                                      

#####################################################################
# tree
# Recursive directory/file listing of present working directory 
#
# tree /Users/foo/foo_dir
# Recursive directory/file listing of named directory, e.g foo_dir
#
# tree /System/Library/ 2
# Recursive directory/file listing of named directory, 
# with-user defined depth of recursion, e.g. 2 
#####################################################################

tree ()
{
    [ -n "$2" ] && local depth="-maxdepth $2";
    find "${1:-.}" ${depth} -print 2> /dev/null | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
}

Просто добавьте функцию в /Users/foo/.profile или .bash_profile , затем обновите профиль с помощью: source .profile или: source .bash_profile

0
  1. Установить Xcode

  2. Получить инструменты командной строки

xcode-select --install
  1. Установить Homebrew
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  1. Установить дерево
brew install tree

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .