テキストファイルから単語リストのすべての項目を削除するには?

テキストファイルから単語リストのすべての項目を削除するには?

単語リストを含むファイルがあります。大きなテキストファイルからこのファイル内のすべての単語をすべて削除したいです。

例:

ファイル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!

私の単語リストは膨大です(50,000単語以上)。コマンドラインでモードを指定せずにこれを行うにはどうすればよいですか?

答え1

実際のユースケースについてはお勧めします。Perlを使ったterdonの答え

ただし、他の単語の部分文字列(「hiking」から「king」を削除)を処理しない単純なバージョンは次のとおりです。1 つの Sed コマンドを使用して別の Sed インスタンスで実行されるコマンドの生成実際のファイルに。

この場合、wordfile「King」と「Queen」が含まれ、textfileテキストが含まれます。

sed -e "$(sed 's:.*:s/&//ig:' wordfile)" textfile

i大文字と小文字を無視する」フラグは、標準ではなくGNU拡張です。

答え2

単純だが非効率的な方法は、各入力ワードごとにファイルを複数回処理することです。

$ 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を使用すると、これを一度に実行できます。

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。これを防ぐには、単語を定義する文字を明示的に一覧表示する必要があります。

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でコードを書くように指示したので、UTF-8エンコーディングで入力する必要があります。ファイルの内容とstdoutを使用して、ロケールの文字セットをデコード/エンコードします。perl-Mutf8-Mopen=locale

答え3

このスクリプトをファイルに保存しますdGITHUBから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

または

bash ./d LIST FILE > NewFile

LIST WORDを読み、正規表現形式に変更しました。たとえば、queenおよびを次の形式にking変更しました。test

queen\|king\|test

次に、sedこのパラメーターを使用してコマンドを作成します。

sed -e 's_\(queen\|king\|test\) *__ig' FILE

このbashスクリプトを使用して、我々は交換するためにLISTWORD読み続けました。FILE

関連情報