xargs を使用して、非対話型シェルに環境変数として配列を保存します。

xargs を使用して、非対話型シェルに環境変数として配列を保存します。

これが続く非対話型シェルの環境変数として配列を保存する - Think Tank 101 - CC 著作権ベースの Q&A 共有プラットフォーム先行は達成するのが難しい、別の質問をさせていただきます。


特定の正規表現の一致を含むすべてのMarkdownファイルを見つけて、ファイルの出力(最も多くのクエリを含む)を昇順にソートしたいと思います。

GREP(){
export Regex
xargs -0 -I "{}" bash -c 'grep "${GrepOption[@]}" --only-matching --with-filename --extended-regexp --regexp="${Regex}" "${1}" 2> /dev/null | wc -l | xargs printf "${1}:%s\n" ' _ "{}" \;
}

find . -name "*.md" -print0 | GREP | grep -v ':0$' | sort -n -r -k2 -t:

ユーザーは「${Regex}」と入力します。ここで GrepOptions は、ユーザー入力に応じたオプションの配列です。たとえば、GrepOptionsはGrepOptions=("--ignore-case")grepオプションの別の配列にすることができます。

GrepOptionsただし、サブシェル環境ではアレイを使用できません。

どんな提案がありますか?

ベストアンサー1

問題は、GrepOptionsコード内の配列を環境変数として使用することです。配列をエクスポートできないため、これを行うことはできません。

bash -c代わりに実行するには、パス名とともにオプションをスクリプトに渡す必要がありますgrep

以下では、さらに一歩進んで、正規表現と複数の発見されたパス名を渡し-execました。findxargs

パス名からユーザーオプションを区切るために--スクリプト呼び出しに使用します。bash -c

find . -name '*.md' -type f -exec bash -c '
    re=$1; shift
    while [[ $1 != "--" ]]; do
        opts+=( "$1" )
        shift
    done; shift

    for pathname do
        printf "%s:" "$pathname"
        grep -o -E -e "$re" "${opts[@]}" -- "$pathname" |
        wc -l | tr -d "[:blank:]"
    done | grep -v ":0$"' bash "$user_regex" "${user_options[@]}" -- {} + |
sort -t : -k2,2n

.md次に、現在のディレクトリまたは次のディレクトリで終わるファイル名を持つすべての一般的なファイルを見つけます。これらのファイル配置では、ユーザー提供bashの拡張正規表現($user_regex)、一部のユーザー提供のコマンドオプションgrep$user_options、配列)、およびパス名の配置を使用するスクリプトが実行されます。

インラインスクリプトは正規表現とユーザーオプションを選択し、見つかったファイルを繰り返しながらgrep各ファイルを実行し、返された行数を計算します。

各ファイルパス名は、最後の1文字の後にこの数字を出力します:

一致するものがないことを示す出力は削除され、結果全体がランク付けされます。

このコードは、パス名の処理方法により、改行やコロンを含むパス名をサポートしません。さらに、配列user_optionsには個別の二重ダッシュを含めることはできません。

おすすめ記事