あるファイルから別のファイルにある文字列を検索し、存在しない場合は元のファイルから削除します。

あるファイルから別のファイルにある文字列を検索し、存在しない場合は元のファイルから削除します。

あるファイルの各行を調べて、ある行が別のテキスト ファイルのどの行とも一致しない場合は、その行を元のファイルから削除するスクリプトを作成しようとしています。

このスクリプトから求められる入力と出力の例は次のようになります。

入力例: ファイル 1 (グループ ファイル)、

hello
hi hello
hi
great
interesting

           file 2: 
this is a hi you see
this is great don't ya think
sometimes hello is a good expansion of its more commonly used shortening hi
interesting how brilliant coding can be just wish i could get the hang of it

スクリプト出力の例 - ファイル 1 が次のように変更されました:

hello
hi
great
interesting

hi hello2番目のファイルには存在しないため、削除されます。

ここにスクリプトがあります。変数を作成するところまでは機能しているようです。

#take first line from stability.contigs.groups
echo | head -n1 ~/test_folder/stability.contigs.groups > ~/test_folder/ErrorFix.txt
#remove the last 5 character
sed -i -r '$ s/.{5}$//' ~/test_folder/ErrorFix.txt 

#find match of the word string in errorfix.txt in stability.trim.contigs.fasta if not found then delete the line containing the string in stability.contigs.groups
STRING=$(cat ~/test_folder/MothurErrorFix.txt)
FILE=~/test_folder/stability.trim.contigs.fasta
if [ ! -z $(grep "$STRING" "$FILE") ]
    then
        perl -e 's/.*\$VAR\s*\n//' ~/test_folder/stability.contigs.groups
fi

答え1

ある場合は、gnu grep以下を実行できます。

grep -oFf file1 file2 | sort | uniq | grep -Ff - file1

grep内の行の順序を保持する必要がない場合は、最後の を削除しますfile1
にアクセスできない場合はgnu grep、次のようにしますawk

awk 'NR==FNR{z[$0]++;next};{for (l in z){if (index($0, l)) y[l]++}}
END{for (i in y) print i}' file1 file2

答え2

持っている場合は、don_crissti の (承認された) 回答を参照してくださいGNU grep。持っていない場合 (たとえば、標準の Mac OS X では動作しません)、代わりにこのスニペットを bash スクリプトに保存することもできます。myconvert.sh

#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
    if ! grep -Fq "$line" $2
    then
        sed -i '' "/$(echo $line | sed -e 's/[]\/$*.^|[]/\\&/g')/d" $1
    fi
done < "$1"

2つのファイルを引数として呼び出す

./myconvert.sh file1 file2

ただし、while/read の使用法と、を呼び出すことによる明らかなパフォーマンス上の欠点に関する、以下の don_crissti の知識豊富なコメントに注意してくださいsed

関連情報