1

sshを介して操作しているUnixマシンでCコードを検索するために、bashシェルスクリプト(これはあまり経験がありません)を作成しようとしています。

これは私のスクリプトのコードです:

#! /bin/bash

find . \( -name '*.c' -o -name '*.h' \) -exec grep -n '<SEARCH_STRING>' {} + | sed -e "s/^\(\..*\.c\):\([0-9]*\):[ \t]*\(.*\)$/\1 :: \2\n\3\n/" | sed -e "s/^\(\..*\.h\):\([0-9]*\):[ \t]*\(.*\)$/\1 :: \2\n\3\n/" | sed ''/<SEARCH_STRING>/s//`printf "\033[31m<SEARCH_STRING>\033[0m"`/'' | less -R

これは、検索文字列を表すために使用するものにすぎないことに注意してください。もちろん、実際にこれを文字どおりに検索しているわけではありません。

これにはいくつか問題があることに気づきました。まず第一に、コマンド ラインに一番下の行 (#!/bin/bash ヘッダーのない「スクリプト」) を入力すると、実際には問題なく動作し、必要な結果が得られます。特定の文字を bash スクリプトにするときにエスケープする必要があることはわかっていますが、いくつかの (組み合わせた) 文字をエスケープしようとしましたが、常に同じエラーが発生します。

find: missing argument to `-exec'
./code_search.sh: line 4: <SEARCH_STRING>: command not found
sed: -e expression #1, char 43: unterminated `s' command
printf: usage: printf [-v var] format [arguments]
./code_search.sh: line 8: \033[31m<SEARCH_STRING>\033[0m: command not found
sed: -e expression #1, char 46: unterminated `s' command

また、検索文字列をスクリプトにパラメーターとして渡す方がはるかに便利であるため、検索文字列をスクリプトにハードコードするべきではないことに気付きましたが、その方法もわかりません。

前述のとおり、私は bash スクリプトを作成した経験があまりないため、コーディング作業を支援するためにこのスクリプトを作成してみました。ただし、これ以上デバッグに時間を費やすことはできません。これは、上司が私に支払ってくれるものではないためです。同僚に尋ねましたが、誰も助けてくれません。

自分自身で bash シェル スクリプトについてさらに学ぶために多くの努力を払わないのは少し安っぽいことはわかっていますが、前述したように、本当に時間を割くことができません。誰かこのスクリプトを完成させるのを手伝ってくれませんか?

よろしくお願いします!

4

2 に答える 2

0

これは、最後のsedコマンドで、文字<がエスケープされていないためです。二重一重引用符は単に空の文字列''を意味します。<はファイルリダイレクトとして解釈され、シェルはファイル「SEARCH_STRING」からの読み取りを試みます。

sed ''/<SEARCH_STRING>/s//`printf "\033[31m<SEARCH_STRING>\033[0m"`/'' 

に変更する必要があります

sed '/<SEARCH_STRING>/s//'`printf "\033[31m<SEARCH_STRING>\033[0m"`'/' 

また、エラーに続いて、findバージョンはコマンドの最後にある+をサポートしていない可能性がありますman find。この場合、+機能はxargsによって実行できます(ただし、ファイル名にスペースを含めることができる場合、これは失敗する可能性があります)

find . \( ... \) | xargs grep -n '<SEARCH_STRING>'
于 2012-10-04T09:33:49.183 に答える
0

このようにして、エラーは発生しません。

#! /bin/bash

searchstring=$1

find . \( -name '*.c' -o -name '*.h' \) -exec grep -n "$searchstring" {} + \ 
        | sed -e "s/^\(\..*\.c\):\([0-9]*\):[ \t]*\(.*\)$/\1 :: \2\n\3\n/" \
        | sed -e "s/^\(\..*\.h\):\([0-9]*\):[ \t]*\(.*\)$/\1 :: \2\n\3\n/" \
        | sed ''/"$searchstring"/s//`printf "\033[31m""$searchstring""\033[0m"`/'' \
        | less -R

しかし、それはそれが機能するという意味ではありません。いくつかのサンプル入力と目的の出力がなければ、さらに支援することは不可能です。たとえば、3番目sedは私には間違っているようです。

于 2012-10-04T08:58:04.527 に答える