我的系統:
- 作業系統:MacOS / Mac OS X (Mojave 10.14.5)
- 作業系統核心:Darwin (18.6.0)
- 內核:達爾文內核 / XNU (18.6.0 / xnu-4903.261.4~2/RELEASE_X86_64)
- ls:版本未知,但
man ls
提供了 BSD 通用指令手冊中的頁面 - 貝殼:
- Bash:GNU bash,版本 5.0.7(1)-release (x86_64-apple-darwin18.5.0)
- zsh:zsh 5.7.1(x86_64-apple-darwin18.2.0)
在 MacOS 中,在使用 bash 或 zsh 等 shell 的終端 CLI 中,我想使用 (BSD) 命令ls
(或者可能是類似的常見且有用的工具)來列出當前工作目錄以外的目錄的內容,其中~
顯示。
排除最後一個規定,ls
當非當前目錄用作 的參數時,自然可以完成此任務ls
:ls arg
其中arg
是非當前目錄的絕對或相對路徑(例如/absolute/path/to/directory
、~/path/from/home/to/directory
或path/from/current/dir/to/directory
)。
-d
我知道如何使用檔案名稱擴充(又稱“globbing”)和選項(列出目錄而不是其內容)來列出目前目錄中的非備份內容,如下所示:(ls -d *[^~]
或ls -d *[!~]
)。我想要相同類型的結果,但對於非當前目錄。
我幾乎可以透過使用 來實現我想要的ls -d arg/*[^~]
,其中arg
與上面描述的相同,但結果顯示每個內容元素的路徑(即感興趣的目錄中的每個文件和目錄)。我想ls
顯示每個元素而不顯示其路徑,就像使用ls arg
.
在 Linux 中,使用 GNU 命令,我可以使用不列出備份檔案的選項來ls
實現我想要的效果: 。雖然這是我想要的,但我想使用 MacOS 原生的工具(最好是 BSD )來實現這一目標。-B
ls -B arg
ls
注意:我不想使用grep
(例如,ls arg | grep '.*[^~]$'
),因為grep
更改了輸出的格式和顏色。
問題回顧:在 Mac 上,如何列出非目前目錄的內容但不列出備份文件,最好使用ls
?
答案1
您可以ls
在子 shell 中執行:
(cd arg; ls -d *[^~])
答案2
使用bash
及其GLOBIGNORE
shell 變量,以及 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
為 - 分隔模式清單:
將使檔案名稱完成忽略這些模式。
如果您使用其選項,macOS 中的實用basename
程式將接受多個路徑名-a
,並將傳回僅包含這些路徑名的檔案名稱部分的清單。
您顯然可以使用您的模式,而不是使用GLOBIGNORE
(它提供了一種更通用的方法來忽略某些文件名模式擴展)*[!~]
(請注意,它!
否定 shell 中的字符類,同時^
否定正則表達式中的字符類):
unset GLOBIGNORE
basename -a dir/*[!~]
……或者,您可以從 Homebrew 安裝 GNU coreutils 並gls -B
按照您在 Linux 系統上可能習慣的方式使用。
答案3
簡潔的答案是使用子shell在非目前目錄中執行指令:
(cd arg; ls -d *[^~])
但是要建立適用於當前目錄以及任何非當前目錄的通用函數,我們可以將以下內容新增至.bashrc
(或新增至bashrc_aliases_lsBSD
,來源為.bashrc
):
alias ls='/bin/ls'
alias l=''
unalias l
function l () { ( if [[ -n "$@" ]]; then cd "$@"; fi ; /bin/ls -d *[^~] ) }
如果我們違背上面提到的使用 BSD 的偏好,我們可以透過安裝 GNU 核心實用程式(例如,via )並在(或在,來源為)中建立所需的別名(而不是使用上面的程式碼)來ls
毫無問題地使用 GNU :brew install coreutils
.bashrc
bashrc_aliases_lsGNU
.bashrc
alias ls='/usr/local/bin/gls'
alias l='/usr/local/bin/gls -B'
我自己目前的解決方案是使用這兩種結構,並在需要時使用我調用的變數LS_TYPE
和我調用的函數ls-switch
(在 中定義bashrc_aliases
,來源為.bashrc
)在它們之間切換,該函數獲取包含這兩種結構的兩個設定檔之一:
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
}
ls
透過這種安排,和的預設行為是透過第一個定義和選擇要取得哪個設定檔來l
設定的,例如:.bashrc
LS_TYPE
LS_TYPE="BSD"
source ~/.config/bash/bashrc_aliases_lsBSD