便利なファイルおよびディレクトリ操作ライブラリであるを使用する場合はf.el
、 function のみが必要ですf-entries
。
ただし、何らかの理由でこのライブラリを使用したくない場合で、移植性のない *nix ソリューションを使用しても問題ない場合は、ls
commandを使用できます。
(defun my-directory-files (d)
(let* ((path (file-name-as-directory (expand-file-name d)))
(command (concat "ls -A1d " path "*")))
(split-string (shell-command-to-string command) "\n" t)))
上記のコードで十分ですが、説明についてはさらに読んでください。
ドットを取り除く
によるとman ls
:
-A, --almost-all
do not list implied . and ..
split-string
文字列を空白で分割すると、出力を解析できますls
。
(split-string (shell-command-to-string "ls -A"))
ファイル名のスペース
問題は、一部のファイル名にスペースが含まれている可能性があることです。split-string
デフォルトでは、変数split-string-default-separators
の正規表現によって分割されます。これは"[ \f\t\n\r\v]+"
です。
-1 list one file per line
-1
ファイルを改行で"\n"
区切り、唯一のセパレーターとして渡すことができます。これを関数にラップして、任意のディレクトリで使用できます。
(split-string (shell-command-to-string "ls -A1") "\n")
再帰
しかし、再帰的にサブディレクトリに飛び込み、後で使用するためにファイルを返したい場合はどうでしょうか? ディレクトリを変更しls
て . 1 つの解決策は、ls
常に絶対パスを返すようにすることです。によるとman ls
:
-d, --directory
list directory entries instead of contents, and do not dereference symbolic links
ワイルドカードとオプションを使用して絶対パスをディレクトリに渡すと、 How can I list files with their absolute path in linux?-d
に従って、直接のファイルとサブディレクトリの絶対パスのリストが取得されます。. パス構成の説明については、Elisp で、スラッシュが適切に挿入されたパス文字列を取得する方法を参照してください。.
(let ((path (file-name-as-directory (expand-file-name d))))
(split-srting (shell-command-to-string (concat "ls -A1d " path "*")) "\n"))
空文字列を省略
Unix コマンドは出力に末尾の空白を追加する必要があるため、プロンプトは新しい行に表示されます。それ以外の場合は、次の代わりに:
user@host$ ls
somefile.txt
user@host$
あるだろう:
user@host$ ls
somefile.txtuser@host$
カスタム セパレータを に渡すsplit-string
と、この改行が単独の行として扱われます。一般に、これにより、空の行が有効なデータである可能性がある CSV ファイルを正しく解析できます。しかし、ヌル文字列になってしまうので、3 番目のパラメーターとして にls
渡すことでこれを省略する必要があります。t
split-string