sed를 사용하여 텍스트 파일의 제목에서 중복 문자를 어떻게 제거할 수 있나요?
NNAAMMEE
nice - run a program with modified scheduling priority
SSYYNNOOPPSSIISS
nice [-n adjustment] [-adjustment] [--adjustment=adjustment] [command [a$
위는 예시입니다. 구문 분석된 출력을 다음 sed
과 같이 만들고 싶습니다 .
NAME
nice - run a program with modified scheduling priority
SYNOPSIS
nice [-n adjustment] [-adjustment] [--adjustment=adjustment] [command [a$
답변1
방법 1
다음 명령을 사용하여 이 작업을 수행할 수 있습니다 sed
.
$ sed 's/\([A-Za-z]\)\1\+/\1/g' file.txt
예
위의 예제 입력을 사용하여 파일을 만들었습니다 sample.txt
.
$ sed 's/\([A-Za-z]\)\1\+/\1/g' sample.txt
NAME
nice - run a program with modified scheduling priority
SYNOPSIS
nice [-n adjustment] [-adjustment] [--adjustment=adjustment] [command [a$
방법 #2
모든 중복 문자를 제거하는 방법도 있습니다.
$ sed 's/\(.\)\1/\1/g' file.txt
예
$ sed 's/\(.\)\1/\1/g' sample.txt
NAME
nice - run a program with modified scheduling priority
SYNOPSIS
nice [-n adjustment] [-adjustment] [-adjustment=adjustment] [command [a$
방법 #3(대문자만 가능)
OP는 대문자만 제거되도록 수정할 수 있는지 물었습니다. 수정된 방법 #1을 사용하여 이를 수행하는 방법은 다음과 같습니다.
예
$ sed 's/\([A-Z]\)\1\+/\1/g' sample.txt
NAME
nice - run a program with modified scheduling priority
SYNOPSIS
nice [-n adjustment] [-adjustment] [--adjustment=adjustment] [command [a$
위 방법에 대한 자세한 설명
모든 예제에서는 문자 세트 AZ 또는 az의 문자 값이 처음 발견될 때 저장되는 기술을 사용합니다. 문자를 둘러싼 대괄호는 sed
나중에 사용하기 위해 저장된다는 의미입니다 . 그런 다음 값은 즉시 또는 나중에 액세스할 수 있는 임시 변수에 저장됩니다. 이러한 변수의 이름은 \1 및 \2입니다.
그래서 우리가 사용하는 비결은 첫 글자를 일치시키는 것입니다.
\([A-Za-z]\)
그런 다음 방금 저장한 값을 보조 문자로 사용합니다. 이 값은 위의 첫 번째 문자 바로 뒤에 나타나야 합니다. 따라서 다음과 같습니다.
\([A-Za-z]\)\1.
우리는 sed
또한 검색 및 바꾸기 기능을 활용합니다. s/../../g
이는 g
우리가 이 작업을 전 세계적으로 수행하고 있음을 의미합니다.
따라서 한 캐릭터를 만나고 또 다른 캐릭터를 만나면 이를 교체하고 동일한 캐릭터로 대체합니다.
답변2
이 명령은 모든 이중 문자를 제거합니다.
sed 's/\([[:alpha:]]\)\1/\1/g'
\1
내부의 텍스트를 나타내 \(…\)
므로 이 명령의 의미는 뒤에 알파벳 문자가 있는 한 해당 알파벳 문자로만 바꾸십시오.
이는 다음과 command
같이 번역됩니다. comand
필요한 경우 들여쓰기되지 않은 줄로 변환을 제한하는 것이 좋습니다.
sed '/^[[:alpha:]]/ s/\([[:alpha:]]\)\1/\1/g'
이 텍스트는 터미널용으로 렌더링된 매뉴얼 페이지입니다. 여기서 굵은 글씨는 thump: C\bC
굵은 글씨로 표시되고, 여기서는 \b
백스페이스 문자(문자 모양 8, ^H라고도 함)입니다. 제어 문자가 여전히 존재하는 경우 반복되는 문자를 잊어버리고 대신 재인쇄를 제거하십시오.
sed -e 's/.\b//g'
출력 형식을 지정할 수 있는 방법이 있으면 C\bC
굵게 표시하고 _\bC
밑줄을 그어 표시하도록 변환하세요.
sed -e 's/\(.\)\b\1/\e[1m\1\e[22m/g' -e 's/_\b\(.\)/\e[4m\1\e[24m/g' |
sed -e 's/\e[22m\e[1m//g' -e 's/\e[24m\e[4m//g'
sed가 백슬래시 이스케이프를 인식하지 못하는 경우 리터럴 문자를 사용하십시오(Ctrl+H \b
및 Ctrl+[ \e
).
답변3
이는 결코 사소한 작업이 아닙니다. 단순히 이중 문자를 바꾸는 것은 재앙이 될 것입니다. "주의", "잊어버리세요" 또는 (귀하의 경우와 더 관련이 있는) "명령"과 같은 단어에 어떤 영향을 미칠지 생각해 보세요. 아래 스크립트는 간단한 솔루션에 대한 첫 번째 시도입니다. 사전을 사용하여 어떤 단어에 반복되는 문자가 있는지 확인합니다.
#!/usr/bin/perl
use strict;
use warnings;
my $input_file = shift//die "No file name given\n";
my $dictionary = shift//'/usr/share/dict/words';
open my $if,'<',$input_file or die "$input_file: $!\n";
open my $dict,'<',$dictionary or die "$dictionary: $!\n";
my %dictionary;
for(<$dict>){
chomp;
$dictionary{$_}++;
}
close $dictionary;
LINE: while(<$if>){
chomp;
WORD: for my $word ( split /\s+/ ){
print "$word " and next WORD if exists $dictionary{lc $word};
SUBSTITUTION: while($word=~ s{([A-Z])\1}{$1}i){
exists $dictionary{lc $word} and last SUBSTITUTION;
} #END SUBSTITUTION
print "$word ";
} #END WORD
print "\n";
} #END LINE
불러라
[user@host]./myscript.pl input_file optional_dictionary_file >output_file
두 번째 인수를 제공하지 않으면 사전 파일의 기본값은 /usr/share/dict/words
괜찮은 GNU/Linux에서 사용할 수 있는 입니다.
부인 성명:이것은 테스트되지 않았습니다.
지침:
- 최소한 하이픈으로 연결된 단어를 분리합니다("단어"가 무엇인지 확인하기 위해 공백을 사용함).
man
페이지 자체의 내용이 복잡해지지 않도록 중복된 대문자만 제거합니다 .- 예를 들어 16진수에 큰 피해를 줄 수 있습니다
0xFFFF
. - 아마 내가 볼 수 없는 것이 훨씬 더 많을 것이다.
답변4
노력하다:
sed -e 's/\([A-Za-z]\)\1/\1/g'
그냥 삭제 \\+
하면 두 글자만 한 글자로 줄어듭니다. (모든 문자가 복사되었다고 가정하여 작동합니다)
다음 작은 테스트를 시도해 보세요.
echo "PPaayy Atttteenttiioonn ttoo aallll ccoommmmaanndds" > test.txt
sed -e 's/\([A-z]\)\1/\1/g' < test.txt > test2.txt
cat test2.txt