2010-09-29 49 views
3

是否有一個不錯的bash單線程來將文件中的字符串映射到唯一編號?將字符串映射到唯一編號?

例如,

a 
a 
b 
b 
c 
c 

應轉換成

1 
1 
2 
2 
3 
3 

我目前正在實施它在C++中,但一個bash一行程序將是巨大的。

+0

您的文件是否只包含一個字符串? – tangens 2010-09-29 16:47:12

+0

我們只討論單個小寫字符串嗎? – csj 2010-09-29 16:47:30

+0

@csj:其實他們是哈希字符串。 @tangens:字母數字是精確的,但是一行中有一個字符串 – Legend 2010-09-29 16:49:48

回答

10
awk '{if (!($0 in ids)) ids[$0] = ++i; print ids[$0]}' 

這會維護一個名爲ids的關聯數組。每次發現一個新的字符串時,它會爲其分配一個單調遞增的ID ++i

實施例:

jkugelman$ echo $'a\nb\nc\na\nb\nc' | awk '{if (!($0 in ids)) ids[$0] = ++i; print ids[$0]}' 
1 
2 
3 
1 
2 
3 
+0

太棒了...謝謝!剛剛完成我的C++版本:) – Legend 2010-09-29 16:57:51

+1

不錯的一個!你打敗了我*,並*做到了一行。 +1表示我不需要在Awk中初始化一個變量。 – 2010-09-29 17:00:56

+0

來想一想,在我的解決方案中,我使用'看過'變量單元化,甚至沒有考慮它... – 2010-09-30 12:43:59

2
awk 'BEGIN { num = 0; } 
{ 
    if ($0 in seen) { 
     print seen[$0]; 
    } else { 
     seen[$0] = ++num; 
     print num; 
    } 
}' [file] 

(不完全是一個線着,當然。)

+0

是的,但這使得它更清晰:)謝謝! – Legend 2010-09-29 17:00:07

3

awk的解決方案在這裏都很好,但這裏是在純的bash相同的方法(> = 4)

declare -A stringmap 
counter=0 
while read string < INPUTFILE; do 
    if [[ -z ${stringmap[$string]} ]]; then 
     let counter+=1 
     stringmap[$string]=$counter 
    fi 
done 
for string in "${!stringmap[@]}"; do 
    printf "%d -> %s\n" "${stringmap[$string]}" "$string" 
done 
2

無需修改即可輕微修改if

awk '!($0 in ids){ids[$0]=++i}{print ids[$0]}' file 
相關問題