Mac で、できれば BSD コマンド ls を使用して、バックアップ ファイル (~ で終わる) を表示せずに、現在のディレクトリ以外のディレクトリの内容を一覧表示するにはどうすればよいでしょうか。

Mac で、できれば BSD コマンド ls を使用して、バックアップ ファイル (~ で終わる) を表示せずに、現在のディレクトリ以外のディレクトリの内容を一覧表示するにはどうすればよいでしょうか。

私のシステム:

  • OS: MacOS / Mac OS X (Mojave 10.14.5)
  • OS コア: Darwin (18.6.0)
  • カーネル: Darwin カーネル / XNU (18.6.0 / xnu-4903.261.4~2/RELEASE_X86_64)
  • ls: バージョンは不明ですが、man lsBSD 一般コマンドマニュアルのページが表示されます
  • シェル:
    • Bash: GNU bash、バージョン 5.0.7(1)-リリース (x86_64-apple-darwin18.5.0)
    • Zsh: zsh 5.7.1 (x86_64-apple-darwin18.2.0)

MacOS では、bash や zsh などのシェルを使用するターミナル CLI で、(BSD) コマンドls(または同様に一般的で便利なツール) を使用して、現在の作業ディレクトリ以外のディレクトリの内容を一覧表示し、チルダ ( ~) で終わるファイルを除くすべてのファイルを表示したいと思います。

最後の規定を除けば、ls非カレント ディレクトリが の引数として使用される場合、 は当然このタスクを実行しますlsls argここで、 はarg非カレント ディレクトリへの絶対パスまたは相対パス ( /absolute/path/to/directory~/path/from/home/to/directory、 などpath/from/current/dir/to/directory) です。

ファイル名の拡張 (別名「グロビング」) とオプション (ディレクトリをリストし、その内容はリストしない) を使用して、現在のディレクトリ内のバックアップ以外の内容をリストする方法を知っています。-d次のようにします: ls -d *[^~](またはls -d *[!~])。現在のディレクトリ以外のディレクトリに対して、同じ種類の結果が欲しいです。

を使用すると、ほぼ目的を達成できますls -d arg/*[^~]argは上記と同じですが、結果には各コンテンツ要素 (つまり、対象のディレクトリ内の各ファイルとディレクトリ) へのパスが表示されます。lsのように、各要素をパスなしで表示したいと思いますls arg

Linux では、GNU コマンド を使用すると、バックアップ ファイルを一覧表示しないオプションlsを使用して、まさに必要な操作を実行できます。これは私が望んでいる操作ですが、MacOS ネイティブのツール、できれば BSD のツールを使用してこれを実現したいと思います。-Bls -B argls

注:出力の書式と色が変更されるため、 grep(例: ls arg | grep '.*[^~]$')は使用しません。grep

質問の要約: Mac で、バックアップ ファイルではなく、現在のディレクトリ以外の内容を一覧表示するには、どうすればよいでしょうかls

答え1

lsサブシェルで実行できます:

(cd arg; ls -d *[^~])

答え2

bashおよびそのGLOBIGNOREシェル変数を 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(特定のファイル名パターン拡張を無視するより一般的な方法を提供する)を使用する代わりに、明らかに独自のパターンを使用できます*[!~]!シェルでは が文字クラスを否定しますが、^正規表現では が文字クラスを否定することに注意してください)。

unset GLOBIGNORE
basename -a dir/*[!~]

... または、Homebrew から GNU coreutils をインストールし、gls -BLinux システムで慣れているように使用することもできます。

答え3

簡潔な答えは、サブシェルを使用して、現在のディレクトリ以外のディレクトリでコマンドを実行することです。

(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 コア ユーティリティ (たとえば、 経由) をインストールし、(上記のコードを使用する代わりに) (または で、 によってソースされた)で必要なエイリアスを作成することによって、問題なくlsGNU を使用できます。brew install coreutils.bashrcbashrc_aliases_lsGNU.bashrc

alias ls='/usr/local/bin/gls'
alias l='/usr/local/bin/gls -B'

私の現在の解決策は、これら両方の構造を使用し、必要に応じて、呼び出す変数LS_TYPEと呼び出す関数ls-switch( で定義されbashrc_aliases、 によってソース化される.bashrc) を使用して、これら 2 つの構造を含む 2 つの構成ファイルのいずれかをソース化することです。

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設定されます。次に例を示します。.bashrcLS_TYPE

LS_TYPE="BSD"
source ~/.config/bash/bashrc_aliases_lsBSD

関連情報