たとえば、inはa:bc:d:a:hi:p:a
重複エントリを削除しa
、in apple:orange:apple:.:pear:mango:.:apple
-は重複エントリを削除します。apple
答え1
牛に似た一種の栄養アッ回避策(すべての区切り文字が保持されている):
s="apple:orange:apple:.:pear:mango:.:apple"
awk '{ len=split($0,a,/:|:\.:/,seps);
for(i=1;i<=len;i++) printf "%s%s",(!w[a[i]]++? a[i]:""),(i==len? "":seps[i]);
print "" }' <<<"$s"
len=split($0,a,/:|:\.:/,seps)
- 文字列を正規表現パターンで区切られたフラグメントに分割し、フラグメントを配列/:|:\.:/
に保存し、a
区切り文字列をseps
配列に保存します。len
- 分割によって生成された要素/ブロックの数を含みます。
出力:
apple:orange::.:pear:mango:.:
答え2
Pythonソリューションの注文
順序が重要な場合は、Pythonの1行のコードで次のことができます。
$ python -c 'import sys;from collections import OrderedDict; d=OrderedDict( (i,True) for i in sys.argv[1].split(":") );print ":".join(d.keys())' 'apple:orange:apple:.:pear:mango:.:apple'
apple:orange:.:pear:mango
少し長いので、小さなスクリプトで書くことができます。
#!/usr/bin/env python
from collections import OrderedDict
import sys
d=OrderedDict( (i,True) for i in sys.argv[1].split(":") )
print ":".join(d.keys())
次のように使用してください。
$ ./uniq_tokens.py 'apple:orange:apple:.:pear:mango:.:apple'
apple:orange:.:pear:mango
仕組み:
- 処理したい文字列をコマンドライン引数として提供するため、
sys
モジュールを使用して参照します。sys.argv[1]
sys.argv[1]
:
区切り文字を使用してトークンに分割(i,True) for i in sys.argv[1].split(":")
2つの値を持つタプルのリストを作成できます。ここではTrue
ダミー値のみです。OrderedDict
次にそれを取得し、キーと値のペアの辞書を作成します。これはそれを作る「安い」方法です注文したセットそしてリストについて事前理解の代替として。文字列がすでにキーとして存在する場合は、一意のままになります(不要なことをしない限り)":".join()
私たちが分割したすべてのトークンをインポートしてから(d.keys()
ここで使用する)、それを素敵なフル文字列に変換して使用できます。:
- 印刷は自明です。
順序がないが短いPythonソリューション
順序が重要でない場合は、より短い解決策を得ることができます(ただし、これは実際のアプリケーションよりも楽しいものです。おそらく99%の時間にトークンの順序を維持したいと思います)。
$ python -c 'import sys;print ":".join(set(sys.argv[1].split(":")))' 'a:bc:d:a:hi:p:a'
a:p:hi:d:bc
仕組みは簡単です。
- 必要な文字列をコマンドライン引数として渡すので、
import sys
最初のコマンドライン引数を次のように引用する必要があります。sys.argv[1]
- それでは、2番目の部分を開いてみましょう。
sys.argv[1].split(":")
最初は完全な文字列であるトークンのリストが提供され、それを:
個々のトークンの区切り文字として使用します。 set()
上記の文字列のリストを取得し、一意の値を提供します。- これで、この文字列のコレクションを再び完全な文字列に変換する必要があります。これが、区切り文字を使用して
":".join()
すべてのトークンを再接続する理由です。:
print
自明だ。これはPython 2.7構文です。print()
Python 3の場合
以下は、別の文字列を使用したテストです。
$ python -c 'import sys;print ":".join(set(sys.argv[1].split(":")))' 'apple:orange:apple:.:pear:mango:.:apple'
orange:mango:pear:apple:.
答え3
Perlのハッシュデータ型を使用して重複を削除できます。
$ cat ./remove_dup.pl
#!/usr/bin/perl -w
use strict;
my $input = shift;
my %seen;
my $order=1;
foreach my $dir ( split /:/, $input ) {
$seen{$dir} = $order++ unless ($seen{$dir}) ;
}
my $output = join( ':', sort { $seen{$a} <=> $seen{$b} } keys(%seen));
print $output . "\n";
デモ:
$ ./remove_dup.pl a:bc:d:a:hi:p:a
a:bc:d:hi:p
$ ./remove_dup.pl apple:orange:apple:.:pear:mango:.:apple
apple:orange:.:pear:mango
答え4
一方bash
通行:
strjoin() { local IFS="$1"; echo "${*:2}"; }
dedup() {
declare -A valbag
IFS=: read -r -a vals <<<"$1"
for ((i=0; i < ${#vals[@]}; i++)); do
(( valbag[${vals[i]}]++ > 0 )) && vals[i]=''
done
strjoin : "${vals[@]}"
}
$ dedup apple:orange:apple:.:pear:mango:.:apple
apple:orange::.:pear:mango::
$ dedup 'a:bc:d:a:hi:p:a'
a:bc:d::hi:p:
これは、すべてのコロンを所定の位置に維持し、コロン間の重複項目のみを消去するというあなたの意見要件を満たします。