回答:
a*
そして*a*
構文はしないことによって、シェルによって実装されるls
コマンド。
入力するとき
ls a*
シェルプロンプトで、シェルはa*
、名前がで始まる現在のディレクトリ内の既存のすべてのファイルのリストに展開されますa
。たとえばa*
、シーケンスa1 a2 a3
に展開し、それらを引数として渡すことができますls
。ls
コマンド自体は見たことがない*
文字を、それだけで3つの引数を見てa1
、a2
とa3
。
ワイルドカード拡張の目的で、「ファイル」は現在のディレクトリ内のすべてのエンティティを指します。たとえばa1
、通常のファイル、a2
ディレクトリ、およびa3
シンボリックリンクなどです。それらはすべてディレクトリエントリを持ち、シェルのワイルドカード拡張は、それらのエントリが参照するエンティティの種類を気にしません。
実際に実行される可能性のあるすべてのシェル(bash、sh、ksh、zsh、csh、tcshなど)は、ワイルドカードを実装しています。詳細は異なる場合がありますが、*
0個以上の文字と?
単一の文字を一致させる基本的な構文は合理的に一貫しています。
特にbashの場合、これはbashマニュアルの「ファイル名展開」セクションに記載されています。実行info bash
して「ファイル名展開」を検索するか、こちらをご覧ください。
これが個々のコマンドではなくシェルによって実行されるという事実は、いくつかの興味深い(そして驚くべき)結果をもたらします。一番いいのは、ワイルドカードの処理が(ほとんど)すべてのコマンドで一貫していることです。シェルがこれを行わなかった場合、必然的にいくつかのコマンドは気にならなくなり、他のコマンドは著者が「より良い」と考えた微妙に異なる方法でそれを行います。(Windowsのコマンドシェルにはこの問題があると思いますが、詳しくコメントできるほど詳しくはありません。)
一方、複数のファイルの名前を変更するコマンドを書くことは困難です。あなたが書く場合:
mv *.log *.log.bak
*.log.bak
現在のディレクトリにすでに存在するファイルに基づいて展開されるため、おそらく失敗します。この種のことを行うコマンドはありますが、独自の構文を使用して、ファイルの名前を変更する方法を指定する必要があります。一部のコマンド(などfind
)は、独自のワイルドカード拡張を実行できます。シェルの展開を抑制するには、引数を引用符で囲む必要があります。
find . -name '*.txt' -print
シェルのワイルドカード展開は、コマンドライン引数と既存のファイルのセットの構文に完全に基づいています。それはできませんコマンドの意味で影響を受けること。たとえば、すべての.log
ファイルを親ディレクトリに移動する場合、次のように入力できます。
mv *.log ..
あなたが忘れた場合..
:
mv *.log
.log
現在のディレクトリに2つのファイルが存在する場合、次のように展開されます。
mv one.log two.log
これは名前を変更one.log
して上書きしtwo.log
ます。
編集:そして、52のアップ投票、承認、および達人バッジの後、タイトルの質問に実際に回答する必要があります。
-d
または--directory
オプションのls
ディレクトリのみをリストすることを教えてくれありません。内容ではなく、ディレクトリ自体をリストするように指示します。に引数としてディレクトリ名を指定するls
と、デフォルトではディレクトリの内容が一覧表示されます。これは通常、あなたが興味を持っているものだからです。この-d
オプションは、ディレクトリ自体のみを一覧表示するように指示します。これは、ワイルドカードと組み合わせると特に便利です。入力した場合:
ls -l a*
ls
は、名前がで始まる各ファイルと、名前がで始まる各ディレクトリa
の内容の長いリストを提供しますa
。ファイルとディレクトリのリストが必要な場合は、それぞれ1行で、次を使用できます。
ls -ld a*
次と同等です:
ls -l -d a*
ls
コマンドが*
キャラクターを見ることがないことをもう一度思い出してください。
これが文書化されている場所については、Unixライクなシステムについてman ls
のls
コマンドの文書が表示されます。ほとんどのLinuxベースのシステムでは、ls
コマンドはGNU coreutilsパッケージの一部です。あなたが持っている場合はinfo
、コマンドを、いずれかinfo ls
またはinfo coreutils ls
あなたのより決定的と包括的なドキュメントを与える必要があります。MacOSなどの他のシステムでは、ls
コマンドの異なるバージョンを使用する場合がありますが、コマンドがない場合がありinfo
ます。それらのシステムでは、を使用しますman ls
。そして、ls --help
表示されます比較的短い使用方法のメッセージ(私のシステムで117行)場合、あなたがGNU coreutilsの実装を使用しています。
そして、もちろん、専門家でさえ時々ドキュメントを参照する必要があります。この古典的なジョークも参照してください。
a*
のすべてのファイルのリストに展開します。a
ls subdir/a*
echo
それです。そのため、何が起こっているかを知りたい場合はls a*
、最初に実行しますecho ls a*
echo a*
...シェルはとにかくグロブ拡張を行います
shopt -s failglob
、同じ動作が発生します。設定nullglob
ではなくfailglob
、例えば、原因*nosuchfile*
空の文字列に展開します。
非常に明確にするために、それはls(1)マニュアルページに記載されています。
-d、-- directoryコンテンツの代わりにディレクトリエントリをリストし、シンボリックリンクを逆参照しません。
公平を期すために、「コンテンツではなくエントリ」がおそらくより説明的である可能性があります。
FILEがディレクトリの場合、そのディレクトリの内容をリストするのではなく、ディレクトリエントリ自体を表示します。FILEがシンボリックリンクの場合、リンクが指すファイルの代わりにリンクエントリ自体を表示します。
説明したように、*
(および同様の拡張)の拡張はglob
Unixの専門用語ではbing と呼ばれ、通常はコマンドプロセッサの機能(Unixの用語では「シェル」として知られています)です。したがって、グロビングは他の多くの場所でも使用できます。bingの詳細についてman 7 glob
は、クラシックLinuxディストリビューションのシェルで入力してください(またはこれを参照してください)glob
。
初期のUnixでは、glob
実際により実施された別のプログラムと呼ばれる/etc/glob
(の10ページを参照この古いUNIXマニュアルをそのための文書化)。現在、これはコードライブラリによって提供されるコードルーチンであり、シェルで一般的に使用されています。ソース:ウィキペディア。
ls -d
ディレクトリと同様にファイルをリストする理由について...
ls
manページでは、これがなぜ起こるかが、非常に簡潔な説明と、説明しています。そのため、ここでは詳細な説明を試みています。
デフォルトでls
は、ディレクトリ名を指定するとディレクトリの内容がリストされ、ディレクトリへのシンボリックリンクに対して同じことを行います。この-d
オプションは、「ディレクトリの名前を指定した場合」(bing によって暗黙的に指定することもできますglob
)を意味し、ディレクトリの_name_sのみを表示し、その内容は表示しません。同様に、ディレクトリへのシンボリックリンクの(明示的または暗黙的な)名前を指定すると、参照するディレクトリの内容ではなく、シンボリックリンクのファイル名を表示します。
この-d
オプションは、私が知る限り、どの項目がリストされているかとは関係ありません。:これは、(ソース行うことができますここで)find
そうのように、: find . -maxdepth 1 -type d
。GNUでのみそうする良い方法があるかどうかはわかりませんls
。ここで使用する方法のいくつかの例ですfind
コマンドは。
要約するとls
、デフォルトでは、パス名を指定するとディレクトリの内容が表示されます。-d
この動作を変更し、標準ファイルに対して行われるように、ディレクトリ名のみを表示します。
ドキュメンテーションは、ディレクトリ名を受け取ると、その内容ではなくディレクトリエントリをリストするのではなく、ディレクトリエントリのみをリストするとは言いません。理解するための最良の方法は例です:ls
> {ice} ~ :10:47 % ls -l /
total 97
drwxr-xr-x 2 root root 4096 May 3 00:27 bin
drwxr-xr-x 4 root root 1024 May 3 14:17 boot
drwxr-xr-x 2 root root 4096 Apr 29 13:44 cdrom
drwxr-xr-x 18 root root 4420 May 9 09:58 dev
...
lrwxrwxrwx 1 root root 33 May 3 14:16 vmlinuz -> boot/vmlinuz-3.9.0-030900-generic
lrwxrwxrwx 1 root root 29 May 3 11:07 vmlinuz.old -> boot/vmlinuz-3.8.0-19-generic
> {ice} ~ :10:47 % ls -ld /
drwxr-xr-x 25 root root 4096 May 3 14:16 /
ドキュメントはシェルの一部です。特に、シェルはコマンドを実行する前に特定の順序でさまざまな展開と置換を実行します。
Bourne互換シェルの単語展開のシーケンスは次のとおりです。
そのため、ls
コマンドは*
文字すら見えず、引数はすでに展開されており、すべてのファイルがa*
globパターンに一致しています。これは、ファイル名のグロビングを必要とする各コマンドがこの機能自体を実装する必要があるWindowsとは異なります。