ファイルから新しい行を読み取り、2つの配列と比較します。複数の単語がある場合、結果は記録されません。

ファイルから新しい行を読み取り、2つの配列と比較します。複数の単語がある場合、結果は記録されません。

スタックオーバーフローの熱烈なファンです。私は初心者であり、このサイトで多くの助けを見つけましたが、今は詰まっています。

今日は以下の機能を持っています。

私は新しい行が書かれるたびにテキストファイル(data.txt)を読みました。テキスト行に「pets」配列に含まれる単語が含まれている場合、その行は別のテキストファイルpets.txtに書き込まれますが、他の行は無視されます。

この機能をどのように元に戻すことができますか?

Array(badword)を使用して悪い単語をブロックして、これらの単語がpetlist.logファイルに書き込まれないようにしたいと思います。

ペット、フィルターには以下が含まれます。

pets=(
'Dog'
'Cat'
'Mouse'
'Horse'
)

badword.filterを含む

badword=(
'Stupid'
'Dumb'
'Bad'
)

script.shには以下が含まれています。

#!/bin/bash
source /home/pi/pets.filter
source /home/pi/badword.filter


while IFS='' read -r line
do
while [ "${pets[count]}" != "" ]
do
if [ "${line/${pets[count]}}" != "$line" ] ; then
echo "$line" >> /logs/petslist.log
fi
count=$(( $count + 1 ))
done

ベストアンサー1

badwords実際に配列の場合性格、次のように使用できますgrep -w

-w, --word 正規表現

単語全体を構成する項目を含む行のみを選択してください。テストでは、一致する部分文字列が行の先頭にあるか、単語を作成しない文字が前にある必要があります。繰り返しますが、行の末尾にあるか、単語を形成しない文字が後に続く必要があります。単語を構成する文字は、文字、数字、下線です。 -xも指定した場合、このオプションは適用されません。

だからあなたの場合

# Declare some constants
readonly bad_words_list="stupid dumb bad" \
         out_file="out_file" \
         in_file="in_file"


# The function you want
function filter_bad_words() {
    # Loop for reading line-by-line
    while read -r line
    do
        # Loop through the list
        # Notice that there are no quotes
        for bad_word in ${bad_words_list[@]}
        do
            # Check if there is a bad word
            # Options in grep: quiet, ignore case, word
            if grep -qiw "$bad_word" <<< "$line"
            then
                # Print the line with bad word to stderr
                echo "Line contains bad word: $line" 1>&2

                # Exit from this loop, continue the main one
                continue 2
            fi
        done

        # Save line into the out file
        # This will not be called if line contains bad word
        echo "$line" >> "$out_file"

    # Read from file
    done < "$in_file"
}

これが最も効率的なソリューションであるかどうかはわかりませんが(sedまたはawkを使用することもできます)、少なくともこれは動作し純粋なBashですgrep

編集する:他の処理をせずにこれらの単語をフィルタリングしたい場合は、grep -oここでも使用できます。

# Read file into a variable
filtered="$(< "$in_file")"

# Go through each bad word
for word in ${bad_words_list[@]}
do
    # Filter the word
    filtered="$(grep -iv "$word" <<< "$filtered")"
done

# Save final result
echo "$filtered" > "$out_file"

おすすめ記事