プログラムをラップし、時には引数を追加するために使用されるBash関数

プログラムをラップし、時には引数を追加するために使用されるBash関数

一般的な解決策に興味がありますが、特定の問題の例は、ファイルパスが見つからない場合にコマンドにラップして追加する.bashrc関数を書くことです。grepデフォルトでは、grepがstdinを待つたびに、私は代わりに特定のファイルを検索したいと思います。私の質問は、最終引数が検索パターンのように検索パスであるか(ラッパーで)どのように知ることができるかということです。

$ ls
example_file.txt
$ grep -someopts 'somestring' 'example_file.txt'

これが-someopts実際にgrepに有効なオプションであるとします。
最後のパラメータはパターン(検索用)ですか、それともファイル(検索用)ですか? - オプションの1つの引数が検索するパターンの場合、grepは標準入力を待ちます
。それ以外の場合は、検索するパターンが検索されます。somestringexample_file.txtsomestringexample_file.txt

前者の場合は、検索するファイルをコマンドの最後に追加したいのですが、誤解がなければそのケースを検出できません。唯一の方法は、grepが取ることができるすべての引数を考慮するラッパーのようです。

これは私のラッパー関数です(check_has_path実装する必要がある場合)。

function grep_wrapped() {
    if check_has_path ; then
        grep "$@"
    else
        grep "$@" '/default/filepath.txt'
    fi
}

答え1

方法:コマンドラインのパターンと可能なファイル名からコマンドラインオプションを分離し、オプションではなくコマンドライン引数を評価します。複数の場合はコマンドをそのまま実行し、それ以外の場合はファイルに表示します。

存在するbash

mygrep () {
    local -a opts

    while [ "$#" -gt 0 ]; do
        case "$1" in
            --) opts+=( "$1" ); shift; break ;;
            -*) opts+=( "$1" ) ;;
            *)  break
        esac
        shift
    done

    if [ "$#" -gt 1 ]; then
        grep "${opts[@]}" "$@"
    else
        grep "${opts[@]}" "$@" "/my/file"
    fi
}

この関数はコマンドラインオプションをコマンドラインの残りの部分から分離し、オプションではなく複数のコマンドライン引数(つまり、パターンの外側の引数)があるかどうかを確認します。それ以外の場合、ファイルはコマンドの最後に表示されます。

オプション引数(たとえば)と一緒にオプションを使用すると、機能しないため、やや-e PATTERN欠陥があります。たぶん他の人の出発点として使用できますか?


このユーザーのコメントを見ると明らかです。いいえ実行にはgrep全く興味がありませんが、特定の拡張子を持つファイルを検索することに興味があります。

次のシェル関数を使用すると、これを行うことができます。

extfind () {
    local ext="$1"

    if [ -z "$ext" ]; then
        echo 'Missing extension' >&2
        return 1
    fi

    shift
    local dir="${1:-$HOME}"

    find "$dir" -type f -name "*.$ext"
}

この機能は次のように使用されます。

$ extfind txt

.txt名前が終わるホームディレクトリ内または下のすべてのファイルを探します。

$ extfind "[hc]" /usr/src

名前またはで終わるディレクトリ内またはディレクトリの下の.hすべての.cファイルを見つけます/usr/src

答え2

Pythonesqueを試してみて例外がある場合は、他の操作を実行できます。それは次のとおりです。

function grep_wrapped(){
    grep "$@" <&-
    local rc=$?
    if [ $rc = 2 ]      # probably a read error from closed stdin
    then   grep "$@" /default/filepath.txt
    else   return $rc
    fi
}

すべてのタスクをgrepに任せます。これにより、エラーメッセージが生成される副作用があります。

grep: (standard input): Bad file descriptor

grepで終了コード2が表示された場合はstdinが閉じられているためです。明らかに、stderrをリダイレクトしてファイルまたは変数としてキャプチャし、戻りコードが0または1のときに印刷できます。

関連情報