2011-11-02 45 views
1

我有一個使用awk,sed,grep和其他shell特徵的腳本。使用awk提取文件的所需部分時出現混亂

我都停留在一個地方,以便需要你的幫助......

這是input文件中爲我的問題

[email protected] ~/ah $ cat decrypt.txt 
60 00 00 00 00 17 3a 20 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 02 *00 00 e0 f9 6a 61 61 6e 
65 6b 61 68 61 6e 67 61 79 65 77 6f 64 69 6e* 00 
00 00 03 29 

我的目的是從上述文件 提取00 00 e0 f9 6a 61 61 6e 65 6b 61 68 61 6e 67 61 79 65 77 6f 64 69 6e,也標示在*之上

雖然很明顯,但這些*的顯示清除了這裏的情況,它們實際上並不存在在文件中。

如上圖所示,在文件的最後五個單元..

00 00 00 03 29

這些00簡單填充字節和03指定其墊長度

現在這裏是腳本的一部分提取所需部分:

size=`wc -w decrypt.txt` 
padlen=3 // calculated by some other mechanism 


awk -v size=$size -v padlen=$padlen 'BEGIN {RS=" ";ORS=" ";} {if (NR > 40 
&& NR <=size-padlen-2) print $0}' decrypt.txt | sed '1,1s/ //' 

輸出:

00 00 e0 f9 6a 61 61 6e 
65 6b 61 68 61 6e 67 61 79 65 77 6f 64 69 

我的問題: 最後一個單元6e失蹤

通過終端也試過......

size=68,padlen=3如此循環應該從NR=40 to NR<=63

[email protected] ~/ah $ awk 'BEGIN {RS=" ";ORS=" ";} {if (NR > 40 && NR <= 65) 
print $0}' decrypt.txt | sed '1,1s/ //' 

00 00 e0 f9 6a 61 61 6e 
65 6b 61 68 61 6e 67 61 79 65 77 6f 64 69 6e 00 
00 

工作正常,如果升OOP去高達65。所以也應該高達63

[email protected] ~/ah $ awk 'BEGIN {RS=" ";ORS=" ";} {if (NR > 40 && NR <= 64) 
print $0}' decrypt.txt | sed '1,1s/ //' 

00 00 e0 f9 6a 61 61 6e 
65 6b 61 68 61 6e 67 61 79 65 77 6f 64 69 6e 

工作,但是這是什麼????當我將65減少到64時,會損失兩個00單位。爲什麼會發生這種情況?

也試過這一個,但無法找到這個奇怪的輸出的原因。

[email protected] ~/ah $ awk 'BEGIN {RS="[ \n]";ORS=" ";} {if (NR > 40 
&& NR <=65)print $0}' decrypt.txt | sed '1,1s/ //' 

0002 00 00 e0 f9 6a 61 61 6e 65 6b 61 68 61 6e 67 61 79 65 77 6f 64 

Plase幫我...

可能是我所解釋的比需要更多的問題,但確實需要它。

我對所有這些shell和awk的東西都陌生,所以可能有一個愚蠢的錯誤,我找不到。

請幫我解決這個問題..

Thnx in advance ..

編輯:

60 00 00 00 00 17 3a 20 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 02 

這些固定40個單位的IPv6報頭的,將總是保持相同。

*之間的部分是可變長度的,這就是爲什麼我需要以這種方式工作,否則這將是一個簡單的任務。

回答

2
_padlen=3 _length=23 

awk '{ 
    for (i = NF - l - p - 2; i < NF - p - 2; i++) 
    printf "%s", ($i (i < NF - p - 2 - 1 ? OFS : ORS)) 
    }' l="$_length" p="$_padlen" RS= ORS='\n' decrypt.txt 
+0

+1'RS = ORS ='\ n''。這不在手冊中!好多了'BEGIN {RS =「」; ORS =「\ n」}'';-) – shellter

+0

謝謝:)其實,它在[manual](http://www.gnu.org/s/gawk) /manual/html_node/Other-Arguments.html#Other-Arguments),但它有缺點。 –

+0

我知道命令行參數設置,但我從來沒有想過在那裏設置RS和ORS。 Doah!謝謝! – shellter

0

我做的代碼和一些小的變化能夠得到直到6E *

size=68; padlen=3 ;awk -v size=$size -v padlen=$padlen 'BEGIN {RS=" ";ORS=" ";} {if (NR > 40 && NR <=size-padlen-1) print $0}' decrypt.txt | sed '1,1s/ //' 

我做了尺寸爲68 becos WC WIS打印尺寸和文件名,你必須刪除它當u是路過與awk腳本相同。

注:我還沒有理解你的要求完全

+0

對不起,以前沒有提到,我需要提取的部分是可變長度的。試着簡單地在*之間放置'00 00 e0 f9'。我相信你將無法通過這個提取它。也看到我的編輯。 –

0

如果我理解這個問題的存在:丟棄前40個值和最後n值(其中n是填充+ 2,即在這種情況下3 + 2 = 5),這可能工作:

header=40;padding=5; 
tr -d '\n' <decrypt.txt | 
sed -r 's/\s+/ /g;s/^(\S+\s+){'"$header"'}//;s/(\S+\s*){'"$padding"'}$//' 

訣竅是展開數據,然後選擇你想要的位。