2013-02-17 84 views
1

我寫一個程序,將數據的字段創建用戶名和密碼UNIX的格式化輸出變量

下面是如何格式化數據

MWS1990 XXX-XX-XXXX STASNY, MATTHEW W SO-II BISS CPSC BS INFO TECH 412/882-0581 

這裏是程序

for linePosition in {11..22} 
do 
    holder=`sed -n "${linePosition}p" $1|awk '{print $1}'` 
    holder2=`sed -n "${linePosition}p" $1|awk '{print $12}'` 
    holder3=`sed -n "${linePosition}p" $1|awk '{print $7}'` 
    echo "UserName" 
    echo "$holder" 
    echo "password" 
    echo "$holder2" 
    echo "$holder3" 
done 

它返回像這樣的輸出

UserName 
MWS1990 
password 
412/882-0581 
BISS 

事情2的事情是錯的是

  1. 我想它的用戶名後刪除的一年。因此,上述 示例將只是MWS。我可以添加到holder =`sed -n 「$ {linePosition} p」$ 1 | awk'{print $ 1}'使其僅返回 的前3個字母。 (最好是小寫,但不是必需的)

  2. 我想刪除電話號碼的前6個字母。因此,而不是412/882-0581 如果你正在使用bash的電話號碼將改爲

+0

需要引用http://tldp.org/LDP/abs/html/string-manipulation.html我會寫的頁面提供一個答案來解釋如何在不久的將來需要時提取字符串。 – 2013-02-17 22:31:19

+0

@ rob-kielty:對不起,並不意味着劫持你的答案!看起來我在添加此評論後幾秒鐘點擊「發佈」。 – 2013-02-17 22:33:50

+0

大聲笑沒關係。有多種方法來清理字符串。 :-我把你的答案和奧拉夫的投票結果投給了你。 – 2013-02-17 22:45:32

回答

2

因此,這裏是一個修改後的答案

for linePosition in {11..22} 
do 
    holder=`sed -n "${linePosition}p" $1|awk '{print $1}'` 
    holder2=`sed -n "${linePosition}p" $1|awk '{print $12}'` 
    holder3=`sed -n "${linePosition}p" $1|awk '{print $7}'` 
    echo "UserName" 
    echo `expr match "$holder" '\([A-Z|a-z]*\)'` 
    echo "password" 
    echo ${holder2: -4} 
    echo "$holder3" 
done 

現在我用的是bash字符串替換貼在我張貼在評論的鏈接描述。

不過,我想指出,這個解決方案如下警告

這裏是以下行的bash腳本的簡短描述...

`expr match "$holder" '\([A-Z|a-z]*\)'` 

的反引號執行內殼層你的for循環,他們運行expr命令傳入match,它返回字符串$holder的那部分,該字符串與字符串開始處的正則表達式[A-Z|a-z]*匹配。參考http://tldp.org/LDP/abs/html/string-manipulation.html

現在,如果您的數據文件不是太長,那麼這將是確定的。

但是,如果您的腳本必須處理大型數據文件那麼我建議您在Olaf的解決方案中看起來漫長而艱難。

爲什麼?

如果您正在處理大量文件,或者如果您不知道要由腳本處理的文件的大小,最好避免在for循環內執行子shell 。在那裏,他利用AWK

奧拉夫的解決方案來進行,你需要有一個重要的優勢,所有的工作需要一個單一的過程內發生的處理。而for循環則爲您的文件的每一行分叉並執行一個bash 的新實例。昂貴的操作,放置在for循環中時可能會有風險。

對於您的代碼,我們可以看到當前的for循環受到一小組行的限制,但如果這種情況經常發生變化或者在for循環中引入了一個bug,從而導致它永遠運行,那麼腳本可能會對性能產生負面影響的機器。

因此,儘管我的答案可能更容易適應您的代碼。如果您需要處理大量數據,Olaf的答案會更好。

+0

謝謝!這適用於除返回4個數字的用戶名外。用戶名的前3個字母是做什麼的。 – onTheInternet 2013-02-17 23:05:19

+0

糟糕!你當然是對的。 1秒。 – 2013-02-17 23:07:26

2

,你都可以做這些事情很容易使用bash substring extraction(見here)。

換句話說,是這樣的:

echo ${holder2:0:3} # "MWS" 
echo ${holder3:8:12} # "0581" 

# Or, to begin indexing from the right end: 

echo ${holder3:(-4)} # "0581" 

作爲用於轉換的字符串在擊爲小寫,參見例如ghostdog74的回答here

3

既然你已經使用awk,可以減少所涉及的命令

awk 'NR >= 11 && NR <= 22 { 
    print "UserName"; 
    print tolower(substr($1, 1, 3)); 
    print "password"; 
    print substr($12, 9); 
    print $7;}' $1