2015-06-01 75 views
0

之後,我想是非常複雜的,我用正則表達式很糟糕,所以你們可以幫助。使用SED正則表達式來替換某些字母與數字

看到這個數據源:

User ID:  
a123456 
a12345f 
a1234e6 
d123d56 
b12c456 
c1b3456 
ba23456 

基本上,我想做的事,就是使用正則表達式/ sed的替換字母所有出現爲數字以外的第一個字母。字母將始終匹配他們的字母表位置。例如A = 1,B = 2,C = 3等

所以結果集應該是這樣的:

User ID: 
    a123456 
    a123456 
    a123456 
    d123456 
    b123456 
    c123456 
    b123456 

有也永遠不會是其他任何AJ字母和字符串總是會7個字符長。

任何人都可以點亮一下嗎?謝謝! :)

+0

我會'awk'圍繞使用空'FS'和在[如何僅使用基本awk打印字符的ASCII值]中完成映射(http://stackoverflow.com/a/14223031/1983854) – fedorqui

+0

您確定在輸入中始終有七個字符? –

+0

是 - 始終7.它們是用戶標識。它永遠不會超過7(包括首字母)。 –

回答

3

這裏,你可以使用標準工具cutpastetr做這件事:

$ paste -d'\0' <(cut -c1 file) <(cut -c2- file | tr 'abcdef' '123456') 
a123456 
a123456 
a123456 
d123456 
b123456 
c123456 
b123456 

此連接使用的tr就行了,其餘的結果行的第一個字符,使用空字符串。 tr將第一個列表中找到的每個元素替換爲第二個列表的相應元素。

0

我看不到複雜性。你的樣品看起來像你只是想用數字1-6,以取代7個字符六:

s/^\([a-j0-9]\)[a-j0-9]\{6\}/\1123456/ 

既然放在那裏是由位置決定的數字,我們不關心什麼,這封信(甚至如果它是一封信)。這裏的缺點是我們不保留數字,但他們的樣本數據從未改變過。

如果我們想替換字母,我能想到的,是通過使用多重替換的第一種方法:

s/\(.\)a/\11/g 

s/^\([a-j0-9]\{1\}\)[a-j]/\11/ 
s/^\([a-j0-9]\{2\}\)[a-j]/\12/ 
s/^\([a-j0-9]\{3\}\)[a-j]/\13/ 
s/^\([a-j0-9]\{4\}\)[a-j]/\14/ 
s/^\([a-j0-9]\{5\}\)[a-j]/\15/ 
s/^\([a-j0-9]\{6\}\)[a-j]/\16/ 

具體數字,但不包括第一個字母更換字母這種模式將取代兩個字符序列,保留第一個,因此每個字母必須運行兩次。使用保持空間,我們可以存儲第一個字符並使用簡單的音譯。棘手的部分是加入兩個部分,於是sed注入不需要的換行符。

# Store in hold space 
h 
# Remove the first character 
s/^.// 
# Transliterate letters 
y/jabcdefghi// 
# Exchange pattern and hold space 
x 
# Keep the first character 
s/^\(.\).*$/\1/ 
# Print it 
#P 
# Join 
G 
# Remove the newline 
s/^\(.\)./\1/ 

仍在學習的sed的能力:)

+0

我的示例數據可能有點糟糕。用戶ID會有所不同。例如a743195,d326578,d918222。這些ID可以表示爲d91822b/d9182b2,d918b22,d91h222,d9a8222,dj18222。等。 –

+0

@StevenFalzon是你的樣本數據不好。您總是爲每個輸入集顯示完全相同的輸出,並且您有1個字母與其餘所有字母不同,j,您甚至在您的示例中甚至沒有包含該字母。編輯您的問題,以便您的示例幫助顯示您的問題。 –

2
sed '/[a-j][0-9a-j]\{6\}$/{h;y/abcdefghij/1234567890/;G;s/.\(.\{6\}\).\(.\).*/\2\1/;}' YourFile 
  • 過濾器上的 「數字」 而已
  • 提醒線(對於第一個字母)
  • 改變所有信數字(包括1號)
  • 添加數字的第一種形式(作爲緩衝區中的第二行)
  • 採取第二線路和6最後第一之一的第一信,重新排序和不使用perl保留其他字符
3

爲了通過除第一字母相應的數字替換的線a-j字母:

$ perl -pe 'substr($_, 1) =~ tr/a-j/0-9/' input_file 

a=0,而不是a=1,因爲j將是10(兩位數字)否則。

J = 0,並且不,只使用數字0-9,並且字母只是簡單地替換它們的數字副本,所以不會有後者大於j。

爲了使j=0a=1

$ perl -pe 'substr($_, 1) =~ tr/ja-i/0-9/' input_file 
+0

它看起來像所需的行爲是a = 1,b = 2,...,j = 0,但該方法看起來不錯。 –

1
$ awk 'BEGIN{FS=OFS=""} NR>1{for (i=2;i<=NF;i++) if(p=index("jabcdefghi",$i)) $i=p-1} 1' file 
User ID: 
a123456 
a123456 
a123456 
d123456 
b123456 
c123456 
b123456 

注意的是,上述再現標題行User ID:原樣。到目前爲止,最好的我可以告訴,所有其他發佈的解決方案都會將標題行更改爲Us5r ID:,因爲它們會像在所有後續行上一樣進行字母到數字的轉換。

+1

我試圖搜索如何將每個字母分隔爲字段,只是嘗試FS,似乎OFS也需要實現這一點。做得好 – NeronLeVelu

+1

將FS設置爲空將輸入分隔成字符,但是將值賦給任何字段使用OFS的值重新編譯記錄($ 0),因此將OFS設置爲空也是必需的,以便當$ 0被重新編譯時, chars。 –