2012-03-24 68 views
5

給定一個包含不同語言字符的UTF-8文件,如何獲得它包含的唯一字符數的計數,同時排除一定數量的符號(例如:「!」,「@」,「」 #「,」。「)從這個計數?如何計算文件中唯一字符的數量?

+1

你不能只bash的做到這一點。你需要用bash編寫完整的程序。在這種情況下,最好使用編程語言。 – 2012-03-24 01:16:19

+1

是否有任何特殊原因需要使用「bash」? – paulsm4 2012-03-24 01:16:34

+0

聽起來像作業... – fbernardo 2012-03-24 01:22:46

回答

2

使用一個Perl的一行:

echo -e "aba\ncfg!ഡ.#g" | perl -C7 -ne 'for(split(//)){if ($_ !~ /[[email protected]#.]/) { print $_."\n"}}' | sort | uniq | wc -l 

輸出7

如果你想忽略換行符:

echo -e "aba\ncfg!ഡ.#g" | perl -C7 -ne 'for(split(//)){if ($_ !~ /[[email protected]#.\n]/) { print $_."\n"}}' | sort | uniq | wc -l 

輸出6

+1

perl + bash中的一個班輪你的意思是? – 2012-03-24 03:32:42

+1

@gnibbler我說**使用**一行。你是對的,那是一種無意義的語言 - 寫了一件事意味着另一件事。更正它。感謝您指出。 – 2012-03-24 03:33:36

5

在Python:

import itertools, codecs 

predicate = set('[email protected]#.').__contains__ 
unique_char_count = len(set(itertools.ifilterfalse(
         predicate, itertools.chain.from_iterable(codecs.open(filename, encoding="UTF-8"))))) 

當你遍歷一個文件,你會得到線。 chain將它們連接在一起,因此迭代它可以獲得角色。 ifilterfalse消除符合條件的字符,並將條件定義爲一組禁止字符中的成員資格。

沒有itertools:

import codecs 
disallowed = set('[email protected]#.') 
unique_char_count = len(set(char for line in codecs.open(filename, encoding="UTF-8") for char in line 
           if char not in disallowed)) 

使用set操作:

import codecs 
unique = set() 
any(unique.update(line) for line in codecs.open(filename, encoding="UTF-8")) 
unique.difference_update('[email protected]#.') 
unique_char_count = len(unique) 
+3

我認爲你需要一個*或一個.from_iterable連鎖才能這樣工作。 – DSM 2012-03-24 01:59:55

+1

@DSM謝謝,錯過了'.from_iterable'。還添加了非itertools版本。 – agf 2012-03-24 02:00:44

+1

您可能希望使用該「open」調用指定編碼。 – 2012-03-24 02:40:40

8

這裏有一個bash的解決方案。 :)

bash$ perl -CSD -ne 'BEGIN { $s{$_}++ for split //, q([email protected]#.) } 
        $s{$_}++ || $c++ for split //; 
        END { print "$c\n" }' *.utf8 
+0

「這是一個bash解決方案」...不! ;) – paulsm4 2012-03-24 03:27:21

+0

面頰+1 ;-) – 2012-03-24 17:15:38

+0

tchrist,'-CSD'的腳本等效內容是什麼? – 2012-03-24 17:20:17

2

我就可以把我的好措施無語言要求的選項:

sed 's/[[email protected]#.]//g' /path/to/file | sed 's/./\0\n/g' | sort -u | wc -l 
+1

這甚至不會*在任何地方**關閉***在我的系統上處理UTF-8文件。在'wc'之前,有很多行,比如'0n0n0n0n','0n0n0n0n0n0n0n0n'等等。是的,LANG ='en_US.UTF-8'。你沒有使用POSIX標準的'sed',對嗎? – tchrist 2012-03-24 02:39:01

+0

@Andrew Kandels - 我認爲這是一個很好的解決方案。如果原始文件是16位Unicode,則始終可以使用iconv:'iconv -f utf-16 -t ascii sourcefile | sed's /[[email protected]#.//// g'/ path/to/file | sed's /./ \ 0 \ n/g'| sort -u | wc -l' – paulsm4 2012-03-24 03:22:52

+0

對不起,在UTF-8部分分開。 @ paulsm4的補充應該可以解決這個問題。 – 2012-03-24 14:47:45

1

使用套蟒。 可以說你要找出文件的唯一字符url.txt

f=open('url.txt') 
a='' 
for x in f: 
    x=x.split(' ') 
    for y in x: 
    a+=y 
unique=set(a)-set('@!#.') #add the characters that you wanna neglect in the second set 
print(unique) 
print('unique characters : ',len(unique)) 

可以說URL。TXT包含:

Google --! google.com --! coolest search engine 

facebook --! facebook.com --! biggest social network 

yahoo --! yahoo.com --! biggest web portal 

輸出將是:

{'a', 'G', 'm', '\n', 'n', 'c', 'b', 'e', 'g', 'f', 'i', 'h', 'k', '-', 'l', 'o', 'p', 's', 'r', 't', 'w', 'y'} 
unique characters : 22 
+0

我的答案已經提供了幾個基本相同的Python版本。此外,你的字符串生成器的性能是__terrible__。添加字符串很慢 - 如果你不得不去掉空格並加入這些行,你應該使用'''.join('''。join(x.split())for x in f)',這會更快。請參閱我的答案,瞭解如何在不建立長字符串的情況下執 – agf 2012-03-24 03:29:37

0

一種替代:

filename='/somewhere/my-file-in-utf8' 

iconv -f UTF8 -t UTF16 $filename | tail -c +3 | \ 
perl -pi -e "s/\x00\@//g; s/\x00\!//g; s/\x00\#//g; s/\x00\.//g;" | \ 
od | cut -b 8- | xargs -n 1 | sort | uniq | wc -l 
+1

忘記了獨特的部分,後固定。 – pizza 2012-03-24 04:31:08

3

紅寶石,使用集:

require 'set' 
string = 'ababbbababbabcdcccdbbaaba' 
ignore = 'c' 
(Set.new(string.chars) - Set.new(ignore.chars)).count 
# => 3 
  • string是一個輸入字符串
  • ignore是與字符的字符串以忽略
  • string.chars在字符串
  • Set.new字符的列表使得一組在它外面
  • -給出兩組
  • 之間的差
  • count是元件在所得設定
+2

'ignore.chars'就夠了;它不需要轉換爲一個集合。 – steenslag 2012-03-24 15:54:39

3

另一個紅寶石一個數:

#encoding: utf-8 
string = '@étude#@étude ฒณ!' 
ignore = '[email protected]#.' 
p string.chars.to_a.uniq.join.delete(ignore).size #=>8 
2

我這樣做在Python 3小時的研究後,但我做到了

fname = "temp.txt" 
num_lines = 0 
num_words = 0 
num_chars = 0 
num_uniq = 0 
a = [] 
exclude = ",[email protected]#$" 
with open(fname, 'r') as f: 
    for line in f: 
     words = line.split() 
     for word in words: 
       char = list(word) 
       a = a + char 
     num_lines += 1 
     num_words += len(words) 
     num_chars += len(line) 
print "Lines:%s\nWords:%s\nChars:%s" % (num_lines, num_words, num_chars) 
num_uniq = len(set(a)-set(exclude)) 
print "Unique Characters:%d" % (num_uniq) 

這裏是輸出

Lines:6 
Words:74 
Chars:385 
Unique Characters:26 
相關問題