Mac OS X-Äquivalent zum Ubuntu-Befehl „tree“


Antworten:


438

Sie können den treeBefehl auch unter macOS erhalten. Wenn Sie Homebrew haben , müssen Sie nur Folgendes ausführen:

brew install tree

Lesen Sie weiter für Details.


Mit einem Paketmanager

Es gibt mehrere Paketmanager für macOS. Die beliebtesten sind: Homebrew , MacPorts oder Fink . Sie können beide installieren, aber ich empfehle Homebrew. Installieren Sie nicht mehr als eine davon gleichzeitig!

Befolgen Sie die Anweisungen auf der Website und führen Sie dann einen der folgenden Befehle aus, je nachdem, welchen Paketmanager Sie ausgewählt haben.

Für Homebrew:

brew install tree

Für MacPorts:

sudo port install tree

Für Fink:

fink install tree

Die Paketmanager bieten andere Befehlszeilenprogramme an, einschließlich der GNU / Linux-Programme, die standardmäßig nicht mit macOS geliefert werden.

Installation von der Quelle

Zunächst müssen Sie die Xcode-Befehlszeilentools durch Ausführen installieren xcode-select --install.

Dann laden Sie die treeQuelle . Dann das Makefile ändern , damit es funktioniert zu bekommen , die auch in erklärt @ apuche Antwort unten . Das Auskommentieren der Linux-Optionen und das Deaktivieren der macOS-Optionen sollte ausreichen.

Dann renn ./configure, dann make.

Jetzt müssen Sie die treeBinärdatei an einen Speicherort verschieben, der sich in Ihrem ausführbaren Pfad befindet. Zum Beispiel:

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

Bearbeiten Sie nun Ihre ~/.bash_profile, um Folgendes einzuschließen :

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

Laden Sie die Shell neu und zeigen Sie nun which treeauf /usr/local/bin/tree.


shaunchapmanblog.com/post/329270449/… enthält anscheinend ebenfalls detaillierte Anweisungen, kann jedoch Probleme mit llvm-gcc verursachen, das unter / Developer läuft, wenn Sie Xcode 4.x ausführen. ein bisschen herumspielen sollte reichen.
Ahmed Masud

1
@DavidMoles Da das einfache Ausführen makeunter OS X nicht funktioniert. Zuerst müssen Sie wissen, wie Sie die Xcode-Befehlszeilentools installieren (oder im Allgemeinen eine Vorstellung davon haben, wie Sie Software erstellen), und dann müssen Sie feststellen, dass ein undefiniertes Symbol den Fehler anzeigt. Sie müssen also einige Anpassungen am Makefile vornehmen (wie hier erklärt ). Zu viel Aufwand IMO.
Slhck

3
@ 7stud Viele Leute kennen einige Befehlszeilentools für sehr einfache CLI-Aufgaben und wissen möglicherweise nicht , wie Software kompiliert wird. Die Menschen haben manchmal Schwierigkeiten zu verstehen, was ./configureund makewarum diese überhaupt benötigt werden. Oder sie wollen sich nicht damit befassen. Oder lesen Sie die Hilfedateien. Sie würden lieber so etwas tun apt-get install. Es ist in Ordnung, wenn Sie Installationen von der Quelle bevorzugen (und ich persönlich auch), aber Sie müssen akzeptieren, dass es Lösungen gibt, die von anderen oder vielleicht sogar der Mehrheit der normalen Computerbenutzer leichter wahrgenommen werden.
Slhck

1
Manchmal haben die Leute Probleme zu verstehen, was ./configure und was genau zu tun ist und warum diese benötigt werden. Ich installiere seit 15 Jahren Software von der Quelle und habe keine Ahnung, was ./configureund makewas. Ich weiß nur, dass dies Schritte sind, die ich ausführen muss, um Software zu installieren. Ich lese blind die README- und INSTALL-Dateien und tue, was immer es sagt.
7.

1
@DhruvGhulati Nicht das ich wüsste, aber du könntest grepes umkehren . Like tree | grep -v 'json'oder ähnlich.
Slhck

33

Nicht genau dasselbe, aber ein schneller Weg auf dem Mac ist:

find .

und das ist es. Es listet alle Dateipfade im aktuellen Verzeichnis als Liste auf.


Bei Interesse an einem bestimmten Verzeichnis: find ./ <dir_name>
raspacorp

Wenn Sie nur an Dateien interessiert sind,find . -type f
Jared Beck

2
Ich war nur daran interessiert, ein paar Ebenen tiefer zu gehen, um die Verzeichnisstruktur zu zeigen, die find . -type d -maxdepth 2für mich so funktioniert hat
Matthew Lock,

Besser verwenden, find *wenn Sie keine versteckten Dateien und Verzeichnisse sehen möchten. treezeigt standardmäßig keine versteckten Dateien und Verzeichnisse an.
Asmaier

findist ein 万金油 Werkzeug.
Evan Hu

22

Oder wenn Ihr Administrator Sie keines der Tools installieren brewlässt fink, portkönnen Sie es immer aus der Quelle erstellen:

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

Bearbeiten Sie das Makefile, um den Linux-Teil zu kommentieren und den OSX-Bereich zu entkommentieren:

# 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

Optional: Erzwingen der Farbausgabe

Und während Sie gerade dabei sind, können Sie die mainMethode der tree.cDatei immer bearbeiten und force_color=TRUE;vorher hinzufügen , wenn Sie einen Baum zwingen möchten, die Ausgabe immer einzufärbensetLocale(LC_TYPE,"");

Endlich drücken makeund fertig ist das Bauen treefür den Mac.

Der Tribut geht an Shaun Chapman für seinen ursprünglichen Beitrag in seinem Blog.


Konnte nicht zu Shauns Website gelangen; Vielen Dank für die Hinweise zum Ändern des Makefiles.
Paul Nathan

Insbesondere können Sie hinzufügen force_color = TRUE;. Kein Semikolon und Sie erhalten einen Kompilierungsfehler.
Tgrosinger

1
Ich habe gerade Version 1.7 und statt setLocaledessen gebaut setlocale. Also rein tree.c, du suchst setlocale(LC_TYPE,""); und danke!
Avi Cohen

Gute Antwort. Können Sie einen Hinweis hinzufügen, wie Sie ihn verschieben /bin(oder einen Pfad, damit er global verwendet werden kann)?
Khanh Nguyen

FYI, 1.7.0 unter Yosemite kompilieren Ich habe: warning: format specifies type 'long' but the argument has type 'long long'. Das Update bestand darin, einen Formatbezeichner von %9ldin zu ändern %9lld.
David Moles


18

Es gibt an sich keinen formalen treeBefehl, aber Sie können dies tun:

Speichern Sie das folgende Skript in / 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

Ändern Sie die Berechtigungen, damit Sie sie ausführen können:

chmod 755 /usr/local/bin/tree 

Natürlich müssen Sie möglicherweise Folgendes erstellen /usr/local/bin:

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

Es fehlen alle Möglichkeiten tree, aber dennoch eine nette kleine Lösung.
Slhck

@slhck hehe es war eine schnelle Hack-Lösung ...
Ahmed Masud

Möglicherweise möchten Sie Ihre Variablen jedoch in Anführungszeichen setzen.
Slhck

$ x sollte $ dirlist sein sollte nicht zitiert werden ... wegen der speziellen Erweiterung von "$ @"
Ahmed Masud

1
@JenS. Natürlich können Sie einfach den Befehl find ändern, um dies zu beheben
Ahmed Masud

5

Eine Alternative mit findund awk:

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

4

Ich habe hier eine einfache Lösung gefunden: http://murphymac.com/tree-command-for-mac/

So Hinzufügen Sie folgendes zu Ihrem .bashrc, .bash_profileoder an jedem anderen Ort wird es funktioniert:

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

Das Hinzufügen eines treeBefehls wird nun folgendermaßen gedruckt:

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

3

Hinzufügen eines kleinen Punktes zu @ apuches Antwort auf die Funktion "OSX El Capitan rootless" . make installschlägt fehl, da wir nicht in das /usr/binVerzeichnis schreiben dürfen .

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$

Um dies zu überwinden, einfach bearbeiten Makefilezu müssenprefix = /usr/local


Nun, das funktioniert technisch. Aber es ist invasiv. So könnten Sie wahrscheinlich laufen ./configure --prefix=/usr/localvor dem Laufen makeund , make installund es würde die gleichen Ergebnisse erzielen.
JakeGould

2
@JakeGould Auf jeden Fall verwende ich prefixin solchen Szenarien. configureIn der neuesten Version von tree (1.7.0) ist jedoch noch keine Datei vorhanden . Die INSTALLDatei im entpackten Verzeichnis sagt nur zu verwenden makeund make installsofort.
Vikas027

2

Ich habe das Folgende zu ~ / .bash_profile hinzugefügt, um es in Terminal.app zu verwenden. Einige Kommentare helfen dabei, sich daran zu erinnern, wie find verwendet wird.

##########
## 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'
}

Beispiel für das aktuelle Verzeichnis

$> tree

Beispiel für einen Pfad

$> tree /some/path

2

Hier ist eine Ruby-Skriptlösung, die einen schönen Unicode-Baum zusammen mit nützlichen Metadaten erzeugt.

#!/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

Sie können die meta = …Zeile ändern , um verschiedene anzuzeigende Metadaten zu extrahieren, und die aufgeteilten Teile in der nächsten Zeile von Hand auswählen. Mit etwas mehr Arbeit könnten Sie beliebige ls-Argumente übergeben, um die anzuzeigenden Metadaten auszuwählen.

Beispielausgabe (sieht im OS X-Terminal besser aus als die Schriftart im Stapelüberlauf):

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

2
Vielen Dank für die leichte Lösung! Unter OSX 10.9.5 (laufendes Lager Ruby 2.0.0) musste ich aufgrund eines Fehlers "Keine implizite Konvertierung von true in String (TypeError)" die sechste Zeile der Methode #tree ändern, um file = File.basename zu lesen (path) + (File.directory?(path)? '/': '')
joel.neely

1

Es ist nicht so hübsch wie ein Gnu-Baum ... aber es ist sehr einfach, ein Alias ​​in bash zu erstellen ... Sie können sogar ein wenig Farbe hinzufügen, indem Sie die G-Option auf die ls-Farbe von osx setzen.

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

1
  1. Installieren Sie Xcode

  2. Kommandozeilen-Tools herunterladen

xcode-select --install
  1. Installieren Sie Homebrew
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  1. Baum installieren
brew install tree

1
Bereits in zwei vorherigen Antworten aus den Jahren 2011 und 2016 erwähnt. Brauchen wir eine dritte Antwort, die dasselbe sagt?
Jason S

0

Spät zum Spiel, aber ich hatte die gleiche Frage. Aufgrund von Arbeitsplatzbeschränkungen konnte ich ein Paket nicht von der Quelle oder über einen Paketmanager eines Drittanbieters installieren.

Dies ist meine Implementierung:

# 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'
}

Fügen Sie einfach die Funktion zu /Users/foo/.profileoder hinzu .bash_profileund aktualisieren Sie das Profil mit: source .profileoder:source .bash_profile

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.