단어 목록이 포함된 파일이 있습니다. 큰 텍스트 파일에서 이 파일에 있는 모든 단어를 모두 제거하고 싶습니다.
예:
파일 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" 제거)을 처리하지 않는 간단한 버전은 다음과 같습니다.하나의 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