単語リストを含むファイルがあります。大きなテキストファイルからこのファイル内のすべての単語をすべて削除したいです。
例:
ファイル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
このスクリプトをファイルに保存します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
または
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