GNU findの-printf述語を使用するときに置き換える方法は?

GNU findの-printf述語を使用するときに置き換える方法は?

私の検索コマンド:

find * -type d -printf '%p\n'

結果は次のとおりです。

Icons
Index
Index/Team
Index/Pricing
Index/WhyUs
Navbar
Share

私はこの結果を得たいと思います:

Icons   components/Icons/Exports
Index   components/Index/Exports
IndexTeam   components/Index/Team/Exports
IndexPricing    components/Index/Pricing/Exports
IndexWhyUs  components/Index/WhyUs/Exports
Navbar  components/Navbar/Exports
Share   components/Share/Exports

find コマンドは次のように変更できます。

find * -type d -printf '%p\tcomponents/%p/Exports\n'

しかし、私は次のような結果を得ます。

Icons   components/Icons/Exports
Index   components/Index/Exports
Index/Team  components/Index/Team/Exports
Index/Pricing   components/Index/Pricing/Exports
Index/WhyUs components/Index/WhyUs/Exports
Navbar  components/Navbar/Exports
Share   components/Share/Exports

最初のスラッシュをどのように変更できますか%p

答え1

-printf(GNU実装固有の述語)は、/ / ...を使用した文字列の埋め込み/切り捨てコマンドをfind除いて、他のコマンドを修正するためのいかなる条項も提供しません。%x%5p%-5p%.5p

しかし、ここではそうする必要はありませんfind。シェルを含むzsh:

for f (**/*(N/)) printf '%s\tcomponents/%s/Exports\n' ${f:gs|/||} $f

また、ソートされたリストを提供し、非表示のディレクトリを除外する利点もあります。

findGNUを使用して出力を後処理する場合でも、同じことができます。sortたとえば、次のようになります。gawk

find . ! -name . -type d -print0 |
  sort -z |
  LC_ALL=C gawk -v RS='\0' '
    {
      name = path = substr($0, 3)
      gsub("/", "", name)
      print name"\tcomponents/"path"/Exports"
    }'

または非表示の項目を除外しますzsh。たとえば、次のようになります。

LC_ALL=C find . ! -name . '(' -name '.*' -prune -o -type d -print0 ')' |
  sort -z |
  LC_ALL=C gawk -v RS='\0' '
    {
      name = path = substr($0, 3)
      gsub("/", "", name)
      print name"\tcomponents/"path"/Exports"
    }'

また、find *シェルは*最初に現在のディレクトリのファイルのリストを展開してに渡しますfind。これは次のことを意味します。

  • 現在のディレクトリの隠しファイルは除外されます(ただし、そのファイルがfind見つかったサブディレクトリから除外されます)。
  • -ファイル名が照会述語で始まると、混乱を招く可能性があります。find
  • 最上位レベルのリストはソートされますが(シェルはデフォルトでグローバル拡張をソートするため)、下位レベルのリストはソートされません(シェルはソートされていないfindため)。
  • 現在のディレクトリに隠されていないファイルが多いと、次の問題が発生する可能性があります。引数のリストが長すぎます。find大きすぎるリストを実行しようとしてエラーが発生しました。

find *に置き換えると、そこからファイルを検索し、上記find .findすべての問題を回避できます。これは.(開始点)がリストにあることを意味するため、または! -name .-mindepth 1GNU拡張子)を使用してそれらを除外する必要があり、代わりにGNUを使用することもできますが、./ここで削除した出力にプレフィックスが表示されます。substr($0, 3)find-printf '%P\0'-print0

関連情報