単語のリストを含むファイルがあります。大きなテキストファイルからこのファイル内のすべての単語の出現をすべて削除したい。
例:
ファイル1
queen
king
テキストファイルのサンプル
Both the king and queen are monarchs. Will the queen live? Queen, it is!
これは私が試したものです:
sed -i 's/queen/ /g' page.txt
sed -i 's/Queen/ /g' page.txt
出力
Both the and are monarchs. Will the live? , it is!
私が持っている単語のリストは大きい(50000語以上)。コマンドラインでパターンを指定せずにこれを行うにはどうすればよいですか?
あなたの実際のユースケースでは、私は Perlを使用したterdonの回答 をお勧めします。
ただし、他の単語の部分文字列である単語を処理しない(たとえば、「king」を「hiking」から削除する)単純なバージョンは、次のようになります se one Sed command to generate the command実際のファイルに対して別のSedインスタンス で実行します。
この場合、wordfile
には「king」と「queen」が含まれ、textfile
にはテキストが含まれます。
sed -e "$(sed 's:.*:s/&//ig:' wordfile)" textfile
"i
gnore case"フラグはGNU拡張であり、標準ではないことに注意してください。
単純ですが非効率的な方法は、ファイルを複数回処理することです。1回の入力Wordごとに1回です。
$ while read w; do sed -i "s/$w//ig" file2 ; done < file1
$ cat file2
Both the and are monarchs. Will the live? , it is!
ただし、大きなファイルの場合は非常に遅くなる可能性があります(サブストリングにも一致します)。あなたはPerlを使って1回のパスでそれを行うことができます:
Perl -lpe 'BEGIN{open(A,"file1"); chomp(@k = <A>)}
for $w (@k){s/\b\Q$w\E\b//ig}' file2
\b
は、単語の境界でのみ一致することを確認します。\Q\E
は、$w
が文字どおりに解釈されるようにします。これにより、スクリプトはhiking
に一致しなくなりますが、high-king
には一致します。これを回避するには、Wordを定義する文字を明示的にリストする必要があります。
Perl -Mopen=locale -Mutf8 -lpe '
BEGIN{open(A,"file1"); chomp(@k = <A>)}
for $w (@k){s/(^|[ ,.—_;-])\Q$w\E([ ,.—_;-]|$)/$1$2/ig}' file2
上記の—
非ASCII文字は、UTF-8エンコーディングで入力する必要があります。これは、Perl
が-Mutf8
を使用してコードをUTF-8で記述しているためです。ロケールの文字セットでデコード/エンコードされるファイルとstdoutのコンテンツに-Mopen=locale
を使用しています。
このスクリプトをファイルd
に保存します:( GITHUB Gistからダウンロード )
#!/bin/bash
LIST=${1:?"LIST Word"}
FILE=${2:?"FILE name not set"}
L=$( sed -e ':a;N;$!ba;s_\n_\x00_g' ${LIST}|sed -e 's_\x00_ \\|_g' -e's_\(\\|\)*$__g')
P='s_\('$L'\)__ig'
O="sed -e '$P' ${FILE}"
eval "${O}"
それを実行します:
bash ./d LIST FILE
ファイルを保存したい場合は、次のコマンドを実行できます。
bash ./d LIST FILE | tee NewFILE
OR
bash ./d LIST FILE > NewFile
私はLIST Wordを読んでそれを正規表現形式に変更します。たとえば、queen
とking
とtest
を次の形式に変更します。
queen\|king\|test
次に、このパラメーターを使用してsed
コマンドを作成します。
sed -e 's_\(queen\|king\|test\) *__ig' FILE
このbashスクリプトを使用して、LISTWORD
を1回、置換のためにFILE
を1回読み取ります