Bashスクリプトはファイルから単語を検索し、レポートを生成します。

Bashスクリプトはファイルから単語を検索し、レポートを生成します。

はい、宿題ですが、答えを期待していません。

シナリオでは、すべてのユーザーのホームディレクトリから悪い単語を検索するスクリプトが必要です。ユーザー名、見つかった単語、パスなどの特定の情報を画面に報告するには、スクリプトが必要です。ユーザーに良いか悪いか尋ねて、悪い場合は間違ったファイル名のリストにあるファイルに入れて、良い場合はリストから削除するとスクリプトに表示されなくなります。

これまでは何とかループを作りたいです。私はこれがgrep -r -e kill -e steal /home/*私に必要なもののリストを持っていることを知っています。また、リストは区切り文字で区切られており、それらをパイプして必要な変数を取得できることもわかっています。また、これをファイルに入れることができることも知っています> filename.txt

これを行うためにループを開始する方法がわかりません...

 for each line in filename.txt
 UNAME=...
 LOC=...
 TXT=...
 echo "Username: $UNAME, Line with bad word found: $TXT, and Path and file name: $LOC. Is this a BAD file? (Y)"
 Read YORN

 if ["$YORN" = "Y" ]; then
 >> (line of text from grep) badfiles.txt
 fi

次とか何でも...

必要:(少なくとも)Bomb、Kill、スペースで区切られたフルネーム、quit、Stealなどの悪い単語を見つけるために実行されるスクリプトを作成します。画面に報告し、1 - ユーザー名2 - 間違った単語を含む行3 - パスとファイル名を含むすべての文書を見つけるには、一度実行する必要があります。その後、ファイルがどこにあるかを知るためにスクリプトを変更したり何かを実行したり、プロセスの終了やプログラムの終了(フラグの削除)などの合法的な目的のファイルを無視する必要があります。

私がしたこと:この単語を含むテストするユーザーと文書を作成しました。私はスクリプト(下)を実行し、コマンドの出力をファイルに入れてから、ファイルを1行ずつ繰り返しました。さて、私が正しい方向に向かっていることを確認するために私の変数をエコーするようにしました。

スクリプト:

grep -r -e kill -e Anne -e bomb -e quit -e steal /home/* > /opt/badword.txt

while read line
do
LOC=`echo -e "$line" | cut -d : -f 1`
TXT=`echo -e "$line" | cut -d : -f 2`
UNAME=`echo -e "$line" | cut -d "/" -f 3`
echo $LOC
echo $TXT
echo $UNAME
done <badword.txt

このスクリプト実行の画面出力:

[root@AnneCentOS opt]# ./script4
/home/brownb/doc1
hello my name is xxx i am going to plant a bomb
brownb
/home/brownb/doc2
I want to kill you
brownb
/home/mammaj/doc67
kill process
mammaj
/home/mammaj/doc22
Anne needs to go
mammaj
/home/swiftt/doc
I want to steal a bunch of money so i never have to work again
swiftt
/home/swiftt/doc300
I want to quit this job!
swiftt
[root@AnneCentOS opt]# 

私のbadword.txtから:

/home/brownb/doc1:hello my name is xxx i am going to plant a bomb
/home/brownb/doc2:I want to kill you
/home/mammaj/doc67:kill process
/home/mammaj/doc22:Anne needs to go
/home/swiftt/doc:I want to steal a bunch of money so i never have to work again
/home/swiftt/doc300:I want to quit this job!

最後に、各行の後に行を追加して、ユーザーにこれが良いファイルかどうかを尋ねたいと思います。 A = Yの場合は、ifステートメントを追加してbadword.txtからその行を削除できます。質問の作成方法を知っていますが、ifステートメントではその特定の行を削除する方法があるかどうかはわかりません。私が作成した文書から。

答え1

いくつかのヒント:

  • すべてのホームディレクトリを見つけるために/ homeのみをスキャンする予定です。おそらく、入門Linuxプロセスの範囲をはるかに超えているかもしれませんが、より複雑な設定には実際には適用されません。getent passwd少し良いかもしれませんが、確かにLinux Iの範囲外です。

  • ファイルで悪い単語を探しているかどうかはわかりません。名前またはコンテンツ。名前の場合は、findファイル名を検索する簡単な方法です(find PATHS '(' -iname '*badword1*' -or -iname '*badword2*' -or … ')' -print)。

  • コンテンツを見ている場合は、これがgrep実際に正しい選択です。-H常にファイル名を印刷することもできます。-n(1から計算して行番号を印刷する)または-b(バイトオフセット印刷)も便利です。または、-l一致するファイル名のみが提供されます。 (また、すべてのファイルがプレーンテキストではありません。バイナリファイルの結果は奇妙になる可能性があります。)

  • ファイルから読み取るシェルコマンドはですread。ループ中にユーザーにメッセージを表示する予定なので、stdin以外の場所で読む必要があります(を渡して-u)。通常、whileこれをループで使用します。また、リダイレクトは以下から来ています。後ろにコマンド – この場合、コマンドはフルループです!

    while read -r -u 5 WORD1 WORD2; do
        true   # do something with $WORD1 and $WORD2 here
    done 5<filename.txt
    
  • ほとんどすべてのシェルコマンドと同様に、単語の分割read$IFS。したがって、に設定すると、','コンマに基づいて分割されます。 ☺に設定すると':'便利です。

  • さまざまな方法でパスを分割できます。cut完了し、basename特定dirnameの部品を使用できます。もちろんsedできawkますが、あまりにも過度にすることができます。 Bashを使用している場合は、拡張機能が最も簡単で迅速な方法です。マンページの「パラメータ拡張」の下にあります。たとえば、

    $ foo='/home/bob'
    $ echo "${foo#/home/}"
    bob
    

修正する:

  • 特定の行を削除するのではなく、ユーザーが間違っていると思うすべての行を含む新しいファイルを作成することをお勧めします。ファイルから行を削除するなどの機能を使用できますが、sed実際にはその行なしで新しいファイルを作成することです。一般に、ファイルシステムでは、最後から始まらない限り、ファイルを減らすことはできません。

  • プロンプトは非常に簡単readで、オプションもあります。しかし、5例に含まれているすべての内容を省略したので、驚くべき結果が得られます。

  • set -xデバッグが可能であることを確認してください。

関連情報