空の文字列はいつ現在のディレクトリを示していますか?


8

次のようfindに、現在のディレクトリでいくつかのファイルを収集するために使用するスクリプト

$ find . -name "*.h"
./foo.h

今、私はそれをプレフィックスfoo.hなしで単に出力したいと思い./ます。空の文字列""はシェルコマンドの現在のディレクトリを表すと思いました。しかし、これは与える:

$ find "" -name "*.h"
find: ftsopen: No such file or directory

だから私は間違っていました。今私の質問は、いつ/どのように/どこで/ ..「空の文字列(?)」は、ファイル名またはパス名を期待するコマンドの現在のディレクトリを示していますか?きちんとした啓発的な説明はありますか?

サイドの質問は、検索つべこべは、上記のラ・文字列操作なしで、簡単に解くことができるかどうかである${parameter#word}cutまたはsed


1
find結果の表示方法を操作する-printfパラメータがあります。プレフィックスfind . -name '*.h' -printf '%P\n'を削除し./ます。何をするか見てくださいfind . -name '*.h' -print
Valentin Bajrami 2014年

ありがとう!残念ながら、私のバージョンのfindはこの-printfオプションをサポートしていません。FWIW、strings私の発見は与える@(#)PROGRAM:find PROJECT:shell_cmds-175!??
phs 2014年

5
@phsこれは、常にOSについて言及することが不可欠になるようなものです。
terdon

回答:


11

昔( 第7版32V4.2BSD4.3BSD)、システムコールレベルで、現在の作業ディレクトリを示す長さゼロのパス名(ルックアップに使用された場合)。ファイルまたはディレクトリ)。 システムIII、すべての状況下で長さがゼロのパス名を使用するとエラーであり、POSIX標準は、このパス名の解像度について言うことがあります。

nullパス名は正常に解決されません。


3
$ PATH、$ MANPATH、$ LD_LIBRARY_PATHの空の文字列(およびその他すべての$ * PATHの文字列である必要はありません)は、現在のディレクトリを示します。dir/ほとんど同じであるdir/.
ステファンChazelas

4

以下を使用できます。

find * -name "*.h"

現在のディレクトリにある名前で始まる.ファイルは省略され、名前がで始まるファイル-はオプションとして解釈されfindて大混乱を引き起こすため、これはとは一般的に同等ではありませんfind . …

「で終わる文字列の不在の/ファイル名の一部としては、」意味カレントディレクトリを、それは、現在のディレクトリがされるという意味ではありません表記間違いなく文字列が存在しない場合と同じではありません空の文字列(で印刷すると同じように見える場合があります)。


4

一般的に、空の文字列は現在のディレクトリを示すものではなく、シェルコマンドやシステムコールを示すものでもありません。一部の古いシステムでは実行されましたが、POSIX準拠システムでは実行されませんでした

空の文字列を渡したときに現在のディレクトリを使用し、プログラムがディレクトリ名を要求するプログラムを見つけることがあります。これは意図的に行われることもあり、指定された文字列がスラッシュで始まらない場合に、現在のディレクトリの絶対パスを先頭に追加することによる副作用もあります。

あなたにとって最良のことは、を離れること./です。害はありません。

ファイルのリストが

find . … | sed 's!^\./!!'

これは改行を含むいくつかのファイル名を壊すことに注意してください。これは通常、人間による消費では問題にならず、の出力findはあいまいであるため、プログラムの消費には適していません。-print0プログラムの使用に適したを使用している場合は、./とにかく接頭辞について気にする必要はありません。

find * …代わりに使用することもできますfind . …find *、一般的には不適切になるいくつかの欠陥があることに注意してください。

  • . 省略されます。
  • すべてのドットファイル(.または..`で始まる名前のファイル)は省略されます。
  • 現在のディレクトリに名前が始まるファイル名-(または、!or (... と呼ばれるファイル)がある場合、それはオプションまたはによって述語として解釈されfindます。

フィルターが現在のディレクトリを除外する場合、最初のポイントは重要ではありません。2番目の点では、パターン..?* .[!.]* *を使用して現在のディレクトリ内のすべてのファイルを照合できますが、各パターンが少なくとも1つのファイルと一致するかどうかを確認し、一致しない場合は省略する必要があります。これは可能ですが、非常に面倒です。最後のポイントはストッパーです。そのfind *ため、Quickieコマンドラインでの使用には適していますが、スクリプトでは使用しないでください。

別のアプローチは、シェルの再帰的グロビング機能を使用することです、例えば

printf '%s\n' **/*.h

これはshopt -s globstar、bashおよびset -o globstarksh93でアクティブにする必要があり、ダッシュなどの基本的なPOSIXシェルには存在しません。デフォルトでは、ドットファイルはトラバースされません。それらを含めるには、最初にグロビングshopt -s dotglobがbashまたはFIGNORE='@(.|..)'ksh93にあるドットファイルを無視しないようにします。また、一致するものがない場合、このコマンドはパターンを出力します。shopt -s nullglob代わりにbashで実行して空の行を出力し、~(N)**/*.hkshでパターンを使用します。

zshでは、再帰的グロビングはデフォルトでオンになっています。glob修飾子Dを使用してドットファイルを含めN、一致がない場合は空行を出力します(デフォルトでは、パターンがどのファイルとも一致しない場合、zshはエラーをスローします)。printf上記のように使用できます

print -rl -- **/*.h(DN)

これらのすべてのヒントをありがとう。での欠陥のほとんどはfind *私にとって新しいものであり、いくつかは恐ろしいです!
2014年

2

空の文字列が現在のディレクトリを示す例は考えられません.。あなたはのような呼び出しを考えているかもしれませんlsが、それはパラメーターが指定されていないls場合は現在のディレクトリを想定し、実際には空の文字列を取得しないためです。

ulmi@silberfisch:~$ ls ""
ls: cannot access : No such file or directory

3
空の文字列が現在のディレクトリを示す1つの例は、PATHコンポーネントとしてのものです。
hvd 2014年

0

先頭を付けずにfindの出力を取得するために使用できるさまざまなトリックがあります./

  1. findの-printfオプションを使用して、だけを印刷するように指示します%f。を参照してくださいman find

    %f先頭のディレクトリが削除されたファイルの名前(最後の要素のみ)。

    例えば:

    find . -name "*.h" -printf "%f\n"
    
  2. 出力を解析します。

    find . -name "*.h" | sed 's#^./##'
    
  3. @Anthonのトリック

    find * -name "*.h"
    

他の質問と同様に、空の文字列は現在のディレクトリを示すことはありません。さまざまなプログラムが現在のディレクトリをデフォルトとして使用するため、引数なしで実行すると、現在のディレクトリで実行されます。


これはGNUを前提としていますfind。または使用%Pのみ取り除くために./
ステファンChazelas

1
find * -name '*.h'は見つかりますfoo/.bar.h.bar.h、現在のディレクトリにはありません。
ステファンChazelas

0

ファイルが現在のディレクトリにある場合は、次のように使用できますls

$ ls *.sh

サブディレクトリ内のファイルも必要で、ファイル名だけが必要な場合は、次のようにします。

$ find . -name '*.h' -exec basename {} \;

現在のディレクトリとして文字列がないことを取得するコマンドがありますが、基本的には何も入力しないと現在のディレクトリをデフォルトとして取得するためです。は.常に現在のディレクトリ(および..親ディレクトリ)を示します


OPは./のみを削除したいが、findソリューションはすべてのディレクトリコンポーネントを削除する
artm
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.