2014-09-02 81 views
3

每行都有一個單詞和一個數字。我需要以某種方式選擇第n個字母,所有這些字母合起來就會形成一個新單詞。例如:如何從一個字符串中爲文件中的每一行選擇第n個字符?

and 3 
for 3 
map 2 
wrestle 1 

draw 

它有這樣開始

cat char.txt | ... 

,我只允許使用SED(無AWK,Perl中,...)。

我知道如何選擇所有的數字

sed 's/\(.*\) \(.*\)/\2/g' 

或文本

sed 's/\(.*\) \(.*\)/\1/g' 

,我在想

cat char.txt | head -c $(sed 's/\(.*\) \(.*\)/\2/g') | tail -c 1 | sed 's/\n\//g' 

但它不會工作,因爲它贏得了不要重複所有的思路,因爲某些原因,它甚至不會在一條線上工作。

需要一些幫助和指導請

+0

你允許使用shell內置命令,還是你只限於sed? – 2014-09-02 20:55:51

+0

是的,我被允許 – Sensei 2014-09-02 21:18:50

回答

2
while read w n; do echo -n ${w:(($n-1)):1}; done < filename 

輸出:

draw 

${parameter:offset:length}: 
    Substring Expansion. Expands to up to length characters of parameter 
    starting at the character specified by offset. 
+1

幹得好。您可能還想指出您正在使用的bash中的哪個主體,例如**字符串內基於**字符索引**的子字符串提取**。有用的情況下,他們想要找到正確的部分'高級BAsh腳本指南'或'男子bash' – 2014-09-02 20:59:59

+2

請注意,該擴展的偏移量和長度字段已被視爲算術表達式,所以你可以用'$ {word :n-1:1}' – 2014-09-02 21:03:36

+0

@glenn jackman:謝謝你的提示。 – Cyrus 2014-09-02 21:26:39

2

下面是一個sed腳本解決難題,假設數字發現範圍在1-9:

s/ /@@@@@@@@@@/
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 1$/\1/ 
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 2$/\2/ 
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 3$/\3/ 
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 4$/\4/ 
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 5$/\5/ 
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 6$/\6/ 
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 7$/\7/ 
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 8$/\8/ 
s/\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\).* 9$/\9/ 
H 
$!D 
${x;s/\n//g;} 

第一線焊盤與@ S上的當前行的字,以確保有在字字段中的至少10個字符。隨後的9行用指定位置的字符替換模式空間。 H將該字符存儲在保持空間中,前面是換行符。除非最後一行被讀取,否則我們丟棄模式空間並重新開始。如果最後一行已被讀取,我們用保留空間來交換模式空間,保留空間包含我們刪除的換行符所需的垃圾郵件。

保存此文件中的script.sed我們得到

% sed -f script.sed < data 
draw 

實現版本,支持字符偏移範圍1-19迷人的行使作爲練習留給讀者。

我們可以更容易地解決這個難題有awk

% awk '{answer=answer substr($1,$2,1)}END{print(answer)}' < data 
draw 
+0

這個問題指定**沒有awk **(我誤解了它)... – 2014-09-02 21:06:11

+3

@TomFenech作爲復仇,我寫了一個解決這個難題的sed腳本。 :-) – 2014-09-02 21:20:29

+1

我們在此重新定義「Rube Goldberg」成語,即「Grünewald-Fenech」。這很酷。 – 2014-09-02 23:45:30

0

只使用sed的(對不起,避免貓char.txt: - ;

sed -n ':a 
/1$/ !{ 
    s/.// 
    h 
    s/.* \([0-9]\)$/\1/ 
    y/98765432/87654321/ 
    G 
    s/\(.\)\n\(.*\) [0-9]/\2 \1/ 
    b a 
    } 
s/\(.\).*/\1/p' char.txt 

假設你只需要1列至9(單個數字),但可以適應「巨大數字」進行擴展。 它還通過'簡單'每行寫入1個字符(如此垂直)。也可以修改bu重載代碼。

原則:如果最後一個數字是不是1,刪除第一個字符,並減少1。如果它等於1,打印行的第一個字符。

  • 如果測試最後一個數字1由/1$/
  • 減少由翻譯第一個字符的y/98765432/87654321/
  • 刪除使用工作,並保持緩衝存儲器演示完成由s/.//
  • 其他(只修改最後一位部分)通過複製行,只留下數字,減少,添加原始行並重新排列新數字以代替最後一箇舊數字
  • 達到數字= 1,在不進入過程並只保留第一個字符,然後打印它通過s/\(.\).*/\1/p
相關問題