2017-08-24 114 views
2

我有以下結構的文件對齊的話:SED/AWK:在一個文件

# ################################################################# 
# TEXT: MORE TEXT 
# TEXT: MORE TEXT 
# ################################################################# 

___________________________________________________________________ 
ITEM 1 
___________________________________________________________________ 
PROPERTY1:  VALUE1_1 
PROPERTY222: VALUE2_1 
PROPERTY33: VALUE3_1 
PROPERTY4444: VALUE4_1 
PROPERTY55: VALUE5_1 

Description1: Some text goes here 
Description2: Some text goes here 

___________________________________________________________________ 
ITEM 2 
___________________________________________________________________ 
PROPERTY1:  VALUE1_2 
PROPERTY222: VALUE2_2 
PROPERTY33: VALUE3_2 
PROPERTY4444: VALUE4_2 
PROPERTY55: VALUE5_2 

Description1: Some text goes here 
Description2: Some text goes here 

我想其他項目添加到該文件,使用SED或AWK:

sed -i -r "\$a$PROPERTY1:  VALUE1_3" file.txt 
sed -i -r "\$a$PROPERTY2222:  VALUE2_3" file.txt 

等等。因此,我的下一個項目是這樣的:

___________________________________________________________________ 
ITEM 3 
___________________________________________________________________ 
PROPERTY1:  VALUE1_3 
PROPERTY222:  VALUE2_3 
PROPERTY33:  VALUE3_3 
PROPERTY4444:  VALUE4_3 
PROPERTY55:  VALUE5_3 

Description1: Some text goes here 
Description2: Some text goes here 

是參差不齊的。如何像以前的項目一樣將我的值與左側對齊?我可以在這裏看到2個解決方案:

  1. 在將值插入文件時對齊值。
  2. 按照我所做的方式將值插入到文件中,然後將它們對齊。

命令

sed -i -r "s|.*:.*|&|g" file.txt 

漁獲物的屬性和值我要對齊,但我一直沒能正確地對準他們,即

awk '/^.*:.*$/{ printf "%-40s %-70s\n", $1, $2 }' file.txt 

它打印出的文件,但它包含描述值和標籤,如果它們包含空格或破折號,則將其剪切。這只是一個大混亂。

我已經嘗試了更多的命令,基於我在堆棧溢出和一些博客上找到的內容,但沒有做任何我需要的。

注意:描述標記的值不是參差不齊 - 這是因爲我以單獨的方式將它們寫入文件。

我的命令有什麼問題?我如何實現我所需要的?

+0

儘管可以使用sed/awk解決這個問題,但使用更強大的工具可能會更容易解決這個問題。您是否考慮過使用正確的數據結構的完整編程語言(例如perl,ruby,C++)來解決您的問題? – Heinrich

+0

@海因裏希,我想避免使用完整的編程語言,因爲我在bash中有一個幾乎完整的腳本,完全符合我的要求,這是它唯一的問題。由於這個問題(並非如此嚴重),我不希望強迫腳本的用戶安裝不同語言的編譯器或解釋器。 – user2738748

回答

1

當你的文件是沒有標籤,試試這個:

sed -r 's/: +/:\t/' file.txt | expand -20 

在這個作品中,輸出重定向到一個TMPFILE並移動到TMPFILE file.txt

0

你可以使用\ t插入選項卡(而不是空格這就是爲什麼你會得到 '鋸齒' 值)

,而不是

sed -i -r "\$a$PROPERTY1:  VALUE1_3" file.txt 

使用

sed -i -r "\$a$PROPERTY1:\t\tVALUE1_3" file.txt 
+1

使用標籤仍然可能導致鋸齒狀對齊,當一個按鍵的長度是例如兩個選項卡(加上一些空格)長,另一個鍵是三個選項卡(再加上一些空格)。 – Heinrich

+0

@ M.B。無論我插入製表符還是空格,屬性的名稱都不相同,所以我總是會得到鋸齒值。 – user2738748

1

您可以使用gensub和周到的領域分離器照顧到這一點:

for i in {1..5}; do 
    echo $((10 ** i)): $i; 
done | awk -F ':::' '/^[^:]+:.+/{ 
    $0 = gensub(/: +/, ":::", $0); 
    key=($1 ":"); 
    printf "%-40s %s\n", key, $2; 
}' 

相關部分是我們將「:+」替換爲「:::」的位置,然後執行printf將其重新組合。

+0

你正在錯誤地調用gensub()(你正在用'$ 0'填充「多少個替換項」字段),你不需要字符串連接的parens,你不需要尾隨換行符,我無法想象改變':+'到':::'並將FS設置爲':::'應該做的不是將FS設置爲':+'(誰說':::'不存在於VALUE?)或者只是使用幾個sub()。哦,你應該提到它是由於使用'gensub()'而引起的特定於gawk的。 –

0

所有你需要做插入新線時,如被記現有的壓痕:

echo 'PROPERTY732: VALUE9_8_7' | 
awk -v prop="PROPERTY1" -v val="VALUE1_3" ' 
     match($0,/^PROPERTY[^[:space:]]+[[:space:]]+/) { wid=RLENGTH } 
     { print } 
     END { printf "%-*s%s\n", wid, prop":", val } 
    ' 
PROPERTY732: VALUE9_8_7 
PROPERTY1:  VALUE1_3 

但是,加入1線同時是有道理,還是現在還不清楚,所有的其他文字的你'重新補充來自於。

上述內容適用於任何UNIX系統上的任何awk。

如果您的「屬性」實際上並沒有以PROPERTY開頭,那麼您只需編輯您的問題以顯示更加真實的示例輸入/輸出,並告訴/告訴我們如何區分PROPERTY行和Description行;再一次,這個解決方案對於awk來說是微不足道的。