sedを使用して重複文字を削除する方法は?

sedを使用して重複文字を削除する方法は?

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

2番目の引数を指定しないと、辞書ファイルのデフォルト値は/usr/share/dict/wordsまともなGNU / Linuxで利用可能です。

婦人声明:これはテストされていません。

指示:

  • 少なくともハイフンで連結された単語を区切ります(「単語」が何であるかを確認するためにスペースを使用します)。
  • manページ自体の内容が複雑にならないように、重複した大文字のみを削除してください。
  • たとえば、16進数に大きなダメージを与える可能性があります0xFFFF
  • おそらく私が見ることができないものがはるかに多いでしょう。

答え4

努力する:

sed -e 's/\([A-Za-z]\)\1/\1/g'  

ただ削除する\\+と、2文字だけが1文字に減ります。 (すべての文字がコピーされたと仮定して動作します)

次の小さなテストを試してください。

echo "PPaayy Atttteenttiioonn ttoo aallll ccoommmmaanndds" > test.txt
sed -e 's/\([A-z]\)\1/\1/g' < test.txt > test2.txt
cat test2.txt

関連情報