awkは私の要件を満たすことができません。

awkは私の要件を満たすことができません。

私の要件は、シェルスクリプトがファイルのフォルダ名を印刷する必要があることです。

たとえば、comp.class は D:/Practice/HelloWorldPractice/bin フォルダにあります。コマンドを実行した後に出力を取得する必要があります。ゴミ箱

私のコマンドはファイルを検索し、ファイルのフルパスを印刷します。次に、フルパスからファイル名を削除します。最後に、ファイルのフォルダ名を除くすべてのアイテムを削除します。

パスワード

filesDirName="/D/Practice/HelloWorldSagar"
file=comp.class
echo $(find "${filesDirName}" -name ${file}) | awk -F '${file}' '{ print $1 }'| awk -F '${filesDirName}' '{ print $2 }'

出力 空の出力

パスワード

端末に次のコマンドを入力すると正常に動作しますが、変数を介して実行すると出力を取得できません。

echo "$(find "/D/Practice/HelloWorldSagar" -name comp.class)" | awk -F 'comp.class' '{ print $1 }'| awk -F '/D/Practice/HelloWorldSagar' '{ print $2 }'

出力

/ゴミ箱/

答え1

forをフィールド区切り文字として使用することcomp.class(またはコード内の変数拡張を一重引用符で囲む)は、パイプラインで複数のプログラムを互いに実行するのawkと同じように、私にとってはあまり意味がありません。awk

私が理解したのは、comp.classファイルを含むディレクトリのファイル名が必要です。

実行方法は次のとおりです。

topdir='/D/Practice/HelloWorldSagar'
filename='comp.class'

find "$topdir" -type f -name "$filename" \
    -exec sh -c 'basename "$(dirname "$1")"' sh {} ';'

comp.class次に、またはその下で呼び出されるすべてのファイルを見つけます/D/Practice/HelloWorldSagar。パス名が見つかると、短いシェルスクリプトは、見つかったパス名のディレクトリパスのデフォルト名(パス名のファイル名部分)を単に印刷します。

または、ディレクトリを見つけてファイルがあるかどうかを個別にテストします。

find "$topdir" -type d \
    -exec test -f {}/"$filename" ';' \
    -exec basename {} ';'

comp.class$topdirこれは、自分を含む、見つかったすべてのディレクトリに存在するかどうかをテストします$topdir。ファイルが見つかると、見つかったディレクトリのデフォルト名が印刷されます。

2つの方法の違いは、2番目の方法も検出することです。シンボリックリンクcomp.class通常のファイルを指して呼び出されます。

関連:


目的のディレクトリのデフォルト名ではなく、以下の相対パスである場合に備えて、次のようにします$topdir

find "$topdir" -type f -name "$filename" \
    -exec sh -c 'd="$(dirname "$2")"; printf "%s\n" "${d#$1/}"' sh "$topdir" {} ';'

dこれは、ディレクトリ名を変数として抽出し、そのディレクトリパス名の値を$topdir最初から削除して印刷する最初のソリューションのバリエーションです。

関連情報