.cとMakefileの両方を含むフォルダがあります。どのフォルダにこのアイテムがあるかを知る必要があります。このフォルダを見つけるには、Linuxでどのコマンドを入力する必要がありますか?
答え1
そしてzsh
:
has() ()(($#)) $REPLY/$~1(N)
ls -- **/*(/e{has Makefile}e{has \\*.c})
has
引数として指定されたglobが$REPLY
ディレクトリ内のすべてのファイルをチェックすることを確認する関数として定義されます。e
ディレクトリを選択するかどうかを決定するには、glob修飾子でこの関数を使用します。次のzsh機能のいくつかは次のとおりです。
() {compound-command} arguments
:匿名機能です。ここで、関数のコードは次のとおりです(($#))
。パラメータ数が0でない場合はtrueを返します。$~1
:zsh
パラメータ拡張中は、デフォルトでは分割+glob操作は行われません。$~1
要求するには明示的に要求する必要があります。全体的な状況拡張部分はパターンと見なされます$1
。$1
(N)
:有効なグローバル修飾子空のボールこの glob の場合、ファイルに一致しない場合は何も拡張しないように glob に指示します。**/
: すべてのレベルのサブディレクトリ(/e...)
/
:ファイルタイプにのみ一致する別のglob修飾子目次とe{code}
一致するファイルパスワードtrueと確認されます(ファイルはに保存されます$REPLY
)。
D
隠しディレクトリを表示して隠しファイルを考慮するには、c
いくつかのglob修飾子を追加してください。
printf '%s\n' **/*(D/e{has Makefile}e{'has "*.c(#qD)"'})
GNUツールの使用:
LC_ALL=C find . \( -name '*.c' -o -name Makefile \) -print0 |
LC_ALL=C awk -v RS='\0' -v ORS='\0' '
{dirname = $0; sub("/[^/]*$", "", dirname)}
/\.c$/ {hasc[dirname]; next}
{hasMakefile[dirname]}
END {for (dir in hasc) if (dir in hasMakefile) print dir}' |
xargs -r0 ls
隠しディレクトリに入りたくないし、隠しCファイルに興味がない場合は、コマンドを次のfind
ように変更してください。
LC_ALL=C find . -name '.?*' -prune -o \( -name '*.c' -o -name Makefile \) -print0
これは一致するディレクトリのパスと内容を提供しますが、一致するディレクトリが1つしかない場合、そのls
パスは出力されません。パスをディレクトリと一致させたい場合は、に置き換えるls --
ことができます。printf '%s\n'
答え2
これは真剣な答えではありませんが、このような質問は時々SQL-in-Shellを使用するか、その逆の方法を使用できることを願っています。
find . -type f |
awk -F/ -vOFS=/ -vq=\' 'BEGIN{print "create table temp (dir varchar, f varchar);"}
{f=$(NF--); print "insert into temp values(" q $0 q "," q f q ");" }
END{print "select dir from temp group by dir ";
print "having sum(when f like "q"%.c"q" then 1 else 0 end)>0 ";
print "and sum(when f="q"Makefile"q" then 1 else 0 end)=1;"}
' | dosql
答え3
GNU findを使用すると、次のことができます。
find . -type f -name Makefile \
-execdir sh -c '
find . ! -name . -prune -name \*.c -execdir pwd \; -quit
' \;
ここで、まず Makefile という一般的なファイルを探し、次にそのファイルを探すディレクトリを使って sh を起動すると、そのディレクトリでのみ .c ファイルを探し、最初の .c ファイルが見つかったらディレクトリ名を出力します。 cすぐに終了します。