File1とfile2の2つのファイルがあります。
file1
次を含む(単語のみ):
ABC
YUI
GHJ
I8O
file2
には多くの段落が含まれています:
dfghjo ABC kll
njjgg bla bla GHJ
njhjckhv chasjvackvh ..
ihbjhi hbhibb jh jbiibi
以下のコマンドを使用して、file1
のfile2
からWordを含む一致する行を取得します。
grep -Ff file1 file2
(file1
の単語がfile2
で見つかった行の出力を提供します)
file1
にはないfile2
の単語も必要です。
誰でもこの出力を得るのを助けることができます:
YUI
I8O
grep
コマンドを使用していて、awk
またはsed
ループを使用できないため、(pssh
、while
、for
を介して)1つのライナーコマンドを探しています。
awk
の1つの方法を次に示します。
_$ awk 'NR==FNR{a[$1]++; next}{for(i in a){if($0 ~ i){found[i]++}}}END{for(i in a){if(!found[i]){print i}}}' file1 file2
YUI
I8O
_
または、もう少し読みやすくします。
_$ awk 'NR==FNR{
a[$1]++;
next
}
{
for(i in a){
if($0 ~ i){
found[i]++
}
}
}
END{
for(i in a){
if(!found[i]){
print i
}
}
}' file1 file2
YUI
I8O
_
NR==FNR
_:NR
は現在の行番号、FNR
は現在のファイルの現在の行番号です。複数のファイルを処理する場合、最初のファイルを読み取っている間だけ、2つは等しくなります。したがって、これは「これを最初のファイルに対してのみ行う」という簡単な方法です。a[$1]++; next
_:最初のファイルの読み取り中に、各Word(最初で唯一のフィールド)を配列a
に保存し、次の行にスキップします。 next
は、コマンドの残りの部分が最初のファイルに対して実行されないようにします。for(i in a){ if($0 ~ i){ found[i]++ } }
:最初のファイル(配列a
のキー)にある各単語について、現在の行がその単語と一致するかどうかを確認します。含まれている場合は、Wordをfound
配列に保存します。これは、2番目の入力ファイルの各行に対して実行されます。END{ }
_:これは、すべての入力ファイルを処理した後で行います。for(i in a){ if(!found[i]){ print i } }
:a
の各単語について、Wordがfound
配列にもない場合は、そのWordを印刷します。あるいは、いくつかのコアLinuxユーティリティを使用できます。
_$ grep -hoP '\w+' file1 file2 | sort | uniq -u | xargs -I{} grep {} file1
I8O
YUI
_
_$ grep -hoP '\w+' file1 file2
ABC
YUI
GHJ
I8O
dfghjo
ABC
kll
njjgg
bla
bla
GHJ
njhjckhv
chasjvackvh
ihbjhi
hbhibb
jh
jbiibi
_
これにより、各ファイルで見つかったすべての単語が印刷されます。 _-o
_フラグは「行の一致する部分のみを出力する」ことを意味し、_-P
_は_\w
_を使用して「任意のWord文字」を意味するPerl互換正規表現(PCRE)を有効にします(文字、数字、__
_)。
_$ grep -hoP '\w+' file1 file2 | sort | uniq -u
chasjvackvh
dfghjo
hbhibb
I8O
ihbjhi
jbiibi
jh
kll
njhjckhv
njjgg
YUI
_
次に、前のコマンドの出力をsort
および_uniq -u
_を介して渡し、一意の一致のみを保持します。これらは、2つのファイルのいずれかにのみ存在する単語です。
_$ grep -hoP '\w+' file1 file2 | sort | uniq -u | xargs -I{} grep {} file1
I8O
YUI
_
最後に、この一意の単語のリストをxargs
にフィードし、_file1
_にそれらをそれぞれgrep
に入れます。 _file1
_に存在する一意の単語のみが返されるため、_file1
_に存在する一意の単語は_file2
_には存在しません。
このコマンドを試してください:
grep -oFf file1 file2 | grep -vFf - file1
最初にfile1をPATTERNとして使用し、file2のPATTERNと一致する一致する行の一部のみを取得する場合、最初のコマンドで次のようになります。
ABC
GHJ
次に、この出力を入力ファイルPATTERNおよびPATTERNと一致しないfile1の検索行として使用すると、次の結果が得られます。
YUI
I8O
Red Hat Enterprise Linux ESリリース4(Nahant Update 3)でテスト済み
Perlの使用:
メインアルゴリズム+ Perl同等のもの:
Slurp f2 // $f2 = `cat f2`
for all lines in f1 // Perl -nle '....' f1
print if f2 does not have it // print if $f2 !~ /$_/
すべて一緒に:
Perl -nle 'BEGIN {$f2=`cat f2`}
print if $f2 !~ /$_/' f1