2013-05-03 67 views
0

我有一個stanza格式的文件。該文件的示例如下。使用sed/awk處理stanza格式的文件

id_1: 
     id=241 
     pgrp=staff 
     groups=staff 
     home=/home/id_1 
     shell=/usr/bin/ks 
id_2: 
     id=242 
     pgrp=staff 
     groups=staff 
     home=/home/id_2 
     shell=/usr/bin/ks 

如何使用awk或者sed來處理它,在一個單一的線和製表符分隔格式僅返回ID名稱,ID和組?例如爲:

id_1  241  staff 
id_2  242  staff 
+0

除id名外還可以包含':'? – abasu 2013-05-03 08:20:56

回答

0

下面是一個AWK溶液:

0123:

translate.awk

#!/usr/bin/awk -f 
{ 
    if(match($1, /[^=]:[ ]*$/)){ 
    id_=$1 
    sub(/:/,"",id_) 
    } 
    if(match($1,/id=/)){ 
    split($1,p,"=") 
    id=p[2] 
    } 
    if(match($1,/groups=/)){ 
    split($1,p,"=") 
    print id_," ",id," ",p[2] 
    } 
} 

或者通過執行它

awk -f translated.awk data.txt 

爲了完整起見,這裏來縮短版本:

#!/usr/bin/awk -f 
$1 ~ /[^=]:[ ]*$/ {sub(/:/,"",$1);printf $1" ";FS="="} 
$1 ~ /id/   {printf $2" "} 
$1 ~ /groups/  {print $2} 
+0

對於一個相當簡單的工作來說不是太複雜嗎? – abasu 2013-05-03 07:07:32

+0

你有更簡單的* working *解決方案嗎?你是什​​麼意思的複雜? – hek2mgl 2013-05-03 07:09:49

+0

嗨,如果某些id沒有'id_'格式呢?我已經嘗試過,如果(匹配($ 1,/^[A-Za-z0-9 _。/))){'在第3行,但它似乎不起作用。 – Schmidtty 2013-05-03 07:11:29

2

與AWK:

BEGIN { FS="="} 

$1 ~ /id_/ { printf("%s", $1) } 

$1 ~ /id/ && $1 !~ /_/ { printf("\t%s", $2) } 

$1 ~ /groups/ { printf("\t%s\n", $2) } 
+0

這會在ID後留下':'。 – 2013-05-03 09:34:40

0
sed 'N;N;N;N;N;y/=\n/ /' data.txt | awk '{print $1,$3,$7}' 
+0

這會在ID後留下':'。 – 2013-05-03 09:35:03

0

這是通過設置RS一襯墊的方法:

awk 'NR>1{print "id_"++i,$3,$7}' RS='id_[0-9]+:' FS='[=\n]' OFS='\t' file 
id_1 241  staff 
id_2 242  staff 

要求GNU awk,假設ID是遞增的順序從1開始的

如果該ID的順序是任意的:

awk '!/shell/&&NR>1{gsub(/:/,"",$1);print "id_"$1,$3,$5}' RS='id_' FS='[=\n]' OFS='\t' file 
id_1 241  staff 
id_2 242  staff 
0
awk -F"=" '/id_/{split($0,a,":");}/id=/{i=$2}/groups/{printf a[1]"\t"i"\t"$2"\n"}' your_file 

如下測試:

> cat temp 
id_1: 
     id=241 
     pgrp=staff 
     groups=staff 
     home=/home/id_1 
     shell=/usr/bin/ks 
id_2: 
     id=242 
     pgrp=staff 
     groups=staff 
     home=/home/id_2 
     shell=/usr/bin/ks 
> awk -F"=" '/id_/{split($0,a,":");}/id=/{i=$2}/groups/{printf a[1]"\t"i"\t"$2"\n"}' temp 
id_1 241  staff 
id_2 242  staff 
+0

什麼!?你甚至讀過這個問題嗎? – 2013-05-03 10:10:15

+0

對不起更新了我的回答 – Vijay 2013-05-03 10:11:44

0

這可能會爲工作你(GNU sed):

sed -rn '/^[^ :]+:/{N;N;N;s/:.*id=(\S+).*groups=(\S+).*/\t\1\t\2/p}' file 

尋找一條持有id的線,然後獲得接下來的3條線並重新排列輸出。