Mein System:
- Betriebssystem: MacOS / Mac OS X (Mojave 10.14.5)
- Betriebssystemkern: Darwin (18.6.0)
- Kernel: Darwin Kernel / XNU (18.6.0 / xnu-4903.261.4~2/RELEASE_X86_64)
- ls: Version unbekannt,
man ls
gibt aber eine Seite aus dem BSD General Commands Manual - Muscheln:
- Bash: GNU Bash, Version 5.0.7(1)-Release (x86_64-apple-darwin18.5.0)
- Zsh: zsh 5.7.1 (x86_64-apple-darwin18.2.0)
Unter MacOS möchte ich in einer Terminal-CLI mit einer Shell wie Bash oder Zsh den Befehl (BSD) (oder vielleicht ein ähnlich gebräuchliches und nützliches Tool) verwenden, um den Inhalt eines anderen Verzeichnisses als des aktuellen Arbeitsverzeichnisses aufzulisten, wobei alle Dateien außer denen angezeigt werden, ls
die mit einer Tilde ( ) enden .~
Abgesehen von der letzten Bedingung ls
wird diese Aufgabe auf natürliche Weise erfüllt, wenn das nicht aktuelle Verzeichnis als Argument für verwendet wird ls
: ls arg
wobei arg
ein absoluter oder relativer Pfad zum nicht aktuellen Verzeichnis ist (z. B. /absolute/path/to/directory
, ~/path/from/home/to/directory
, oder path/from/current/dir/to/directory
).
Ich weiß, wie man nicht gesicherte Inhalte im aktuellen Verzeichnis auflistet, indem ich die Dateinamenerweiterung (auch „Globbing“ genannt) und die -d
Option (Verzeichnisse und nicht deren Inhalte aufzulisten) verwende, etwa so: ls -d *[^~]
(oder ls -d *[!~]
). Ich möchte die gleichen Ergebnisse, aber für ein nicht aktuelles Verzeichnis.
Ich kann fast das erreichen, was ich will, indem ich verwende ls -d arg/*[^~]
, wobei arg
dasselbe ist wie oben beschrieben, aber die Ergebnisse zeigen den Pfad zu jedem Inhaltselement (also zu jeder Datei und jedem Verzeichnis im betreffenden Verzeichnis). Ich möchte ls
jedes Element ohne den Pfad dazu anzeigen, so wie es mit gemacht wird ls arg
.
Unter Linux ls
kann ich mit dem GNU-Befehl genau das erreichen, was ich will, indem ich die -B
Option verwende, Sicherungsdateien nicht aufzulisten: ls -B arg
. Obwohl das mein Wunsch ist, würde ich dies gerne mit nativen Tools von MacOS erreichen, vorzugsweise BSD ls
.
grep
Hinweis: Ich möchte (zB, ls arg | grep '.*[^~]$'
) nicht verwenden , da grep
dies die Formatierung und Farbgebung der Ausgabe ändert.
Fragenzusammenfassung: Wie kann ich auf einem Mac den Inhalt eines nicht aktuellen Verzeichnisses, jedoch nicht die Sicherungsdateien auflisten, vorzugsweise mit ls
?
Antwort1
Sie könnten ls
in einer Subshell ausführen:
(cd arg; ls -d *[^~])
Antwort2
Verwenden Sie bash
und seine GLOBIGNORE
Shell-Variable zusammen mit dem von macOS basename
:
$ mkdir dir
$ touch dir/file{1,2}{,~}
$ ls -R
dir
./dir:
file1 file1~ file2 file2~
$ GLOBIGNORE=*~
$ ls -d dir/*
dir/file1 dir/file2
$ basename -a dir/*
file1
file2
GLOBIGNORE
Wenn Sie eine Liste mit durch -getrennte Muster festlegen :
, werden diese Muster bei der Dateinamenvervollständigung ignoriert.
Das basename
Dienstprogramm in macOS akzeptiert mehr als einen Pfadnamen, wenn Sie die entsprechende -a
Option verwenden, und gibt eine Liste zurück, die nur aus den Dateinamenteilen dieser Pfadnamen besteht.
Anstatt zu verwenden GLOBIGNORE
(was eine allgemeinere Möglichkeit bietet, bestimmte Mustererweiterungen für Dateinamen zu ignorieren), können Sie natürlich Ihr Muster verwenden *[!~]
(beachten Sie, dass !
eine Zeichenklasse in der Shell negiert wird, während ^
eine Zeichenklasse in regulären Ausdrücken negiert wird):
unset GLOBIGNORE
basename -a dir/*[!~]
... oder Sie installieren einfach GNU Coreutils von Homebrew und verwenden es gls -B
wie gewohnt auf Linux-Systemen.
Antwort3
Die kurze Antwort besteht darin, eine Subshell zu verwenden, um den Befehl im nicht aktuellen Verzeichnis auszuführen:
(cd arg; ls -d *[^~])
Um jedoch eine allgemeine Funktion zu erstellen, die sowohl für das aktuelle als auch für alle anderen Verzeichnisse funktioniert, können wir Folgendes zu .bashrc
(oder zu bashrc_aliases_lsBSD
, Quelle .bashrc
: ) hinzufügen:
alias ls='/bin/ls'
alias l=''
unalias l
function l () { ( if [[ -n "$@" ]]; then cd "$@"; fi ; /bin/ls -d *[^~] ) }
Wenn wir uns der oben genannten Präferenz für die Verwendung von BSD widersetzen, können wir GNU ls
problemlos verwenden, indem wir die GNU-Kerndienstprogramme installieren (z. B. über brew install coreutils
) und die gewünschten Aliase (anstatt den obigen Code zu verwenden) in .bashrc
(oder in bashrc_aliases_lsGNU
, bezogen von .bashrc
) erstellen:
alias ls='/usr/local/bin/gls'
alias l='/usr/local/bin/gls -B'
Meine eigene aktuelle Lösung besteht darin, beide Konstruktionen zu verwenden und bei Bedarf zwischen ihnen zu wechseln. Dazu verwende ich eine Variable, die ich aufrufe, LS_TYPE
und eine Funktion, die ich aufrufe ls-switch
(definiert in bashrc_aliases
, bezogen von .bashrc
), die eine von zwei Konfigurationsdateien als Quelle verwendet, die diese beiden Konstruktionen enthalten:
function ls-switch () {
if [[ $LS_TYPE = "GNU" ]] ; then
LS_TYPE="BSD"
source ~/.config/bash/bashrc_aliases_lsBSD
elif [[ $LS_TYPE = "BSD" ]] ; then
LS_TYPE="GNU"
source ~/.config/bash/bashrc_aliases_lsGNU
fi
}
Bei dieser Anordnung werden die Standardverhaltensweisen von ls
und mit der ersten Definition von und der Auswahl der als Quelle verwendeten Konfigurationsdatei l
festgelegt , zum Beispiel:.bashrc
LS_TYPE
LS_TYPE="BSD"
source ~/.config/bash/bashrc_aliases_lsBSD