2015-11-25 44 views
2

我想打印路由器配置並僅排序以模式「crypto isakmp key 6」開頭的行。重要的是,我想在同一個地方留下這些行,所以在這行之前和之後應該保持在同一個地方(不排序)。BASH排序行以模式開始

例CFG文件:

123 345 
678 901 
bla bla bla 
ble ble ble 
crypto isakmp key 6 kokofeofepokpfowkfpwjeiofjwiojefiow address 123.456.789.012 
crypto isakmp key 6 ofjwiojefiow352okdwofkwkfi9i42kpfsej09f09j4 address 123.456.789.012 
crypto isakmp key 6 9i42kpfsej09f09j4ofjwiojefiow352okdwofkwkfi address 123.456.789.012 
crypto isakmp key 6 9j4ofjwiojefiow352okdwofkwkfi9i42kpfsej09f0 address 123.456.789.012 
ccc ddd eee 
fff ggg hhh iii 
123 456 

所以首先我想打印不變(行的隨機數):

123 345 
678 901 
bla bla bla 
ble ble ble 

然後我想打印SORTED線開始加密ISAKMP密鑰6.

最後我想打印其餘文件不變(也是隨機數行):

ccc ddd eee 
fff ggg hhh iii 
123 456 

我已經被很多操作,包括獲取第一個和最後的位置「加密ISAKMP密鑰6」,用/命令管理這一點,但它是相當複雜的,我不知道是否有選項AWK/SED可能是其他Linux工具來管理它的指定行。請解釋你的命令在步驟中做了什麼。

預期輸出(密碼排序其餘完好):

123 345 
678 901 
bla bla bla 
ble ble ble 
crypto isakmp key 6 9i42kpfsej09f09j4ofjwiojefiow352okdwofkwkfi address 123.456.789.012 
crypto isakmp key 6 9j4ofjwiojefiow352okdwofkwkfi9i42kpfsej09f0 address 123.456.789.012 
crypto isakmp key 6 kokofeofepokpfowkfpwjeiofjwiojefiow address 123.456.789.012 
crypto isakmp key 6 ofjwiojefiow352okdwofkwkfi9i42kpfsej09f09j4 address 123.456.789.012 
ccc ddd eee 
fff ggg hhh iii 
123 456 

問候, 邁克

+0

發佈排序的行以及。分類什麼? – 123

+0

顯示完整的預期輸出,而不僅僅是輸入的頂部和底部以及關於中間的說明。 –

回答

3

不完全明白你的排序是什麼意思,但是這將加密線按字母順序排序,離開別人,因爲他們

所需的GNU AWK的ASORT功能。

awk 'y=/crypto isakmp key 6/{x=1;a[NR]=$0} 
    x&&!y{x=asort(a);for(i=1;i<=x;i++)print a[i];x=0};!x' file 

123 345 
678 901 
bla bla bla 
ble ble ble 
crypto isakmp key 6 9i42kpfsej09f09j4ofjwiojefiow352okdwofkwkfi address 123.456.789.012 
crypto isakmp key 6 9j4ofjwiojefiow352okdwofkwkfi9i42kpfsej09f0 address 123.456.789.012 
crypto isakmp key 6 kokofeofepokpfowkfpwjeiofjwiojefiow address 123.456.789.012 
crypto isakmp key 6 ofjwiojefiow352okdwofkwkfi9i42kpfsej09f09j4 address 123.456.789.012 
ccc ddd eee 
fff ggg hhh iii 
123 456 

說明

y=/crypto isakmp key 6/ 
#variable y is set to 1 if the line contains this regex, 0 if not 
{ 
#The following code block within the brackets is executed if y is non zero 
x=1 
#Set x to 1(i.e true),done every match because it is less hassle and has no negative 
#side effects 
a[NR]=$0 
#Create array element in array a with a key of NR(line number,doesn't actually matter what 
#it is though just has to be unique each line) and a value of $0(the line) 
} 
#End that block 
x&&!y 
#If x(set in the previous block to 1) is set and y isn't (meaning we have encountered a 
#crypto line but the one we are currently on isn't a crypto line) then 
{ 
#Open block like before 
x=asort(a) 
#Sort the array a, and set x to the number of elements 
for(i=1;i<=x;i++) 
#for each element 
print a[i] 
#Print the element , note the loop ends here as we have not enclosed in brackets 
x=0 
#Set x to 0(false) 
} 
#End block 
!x 
#Default action for awk is to print the line if an command returns true, so will print any 
#line where x is not set or is 0 i.e not crypto lines. We could have also used y' 

有意義的名稱

awk 'InBlock=/crypto isakmp key 6/{Stored=1;Lines[NR]=$0} 
    Stored&&!InBlock{ 
     Count=asort(Lines) 
     for(i=1;i<=Count;i++)print Lines[i] 
     Stored=0 
    } 
    !InBlock' file 
+0

似乎它的工作。順便說一句。我的和你的正則表達式中有一個錯誤,我認爲它應該是「^ crypto isakmp key 6」,因爲它只應該匹配起始行。你可以一步一步解釋這個命令是怎麼解釋!y!x &&等等...... :)?謝謝。 – mike

+0

@mike因爲你沒有試圖自己回答這個問題,而且這些都是非常基本的命令,所以我會讓你知道他們爲自己做了什麼。如果在查詢基本的awk語法後,你對腳本的特定部分有任何問題,那麼我會解釋它們。 – 123

+0

我發佈了有問題的答案,但我要求使用AWK或SED的更緊湊版本。這確實有效,但我不明白爲什麼。這就是爲什麼我問如果你可以解釋它是如何工作的。我知道它創建的數組變量NR當前行具有正則表達式,然後它存儲該行內容$ 0,並最終把所有的這些y?不知道爲什麼每個正則表達式命中x = 1。稍後,您可以在「x」之間創建邏輯「&」,它目前是什麼?以及與「排序引擎」相關的y的否定。最後打印否定了x.我仍然不明白所有的步驟:/。 – mike

0

這裏是我做過什麼:

# get interesting lines with numbers 
LINER1=`grep -n "^crypto isakmp key 6" r1` 

# get interesting lines without numbers for later output 
LINER1F=`grep "^crypto isakmp key 6" r1` 

# get whole config rows count 
LENGTHR1=`wc -l r1|awk '{print $1}'` 

# get 1st interesting line number 
STARTR1=`echo "$LINER1" | head -1 | cut -f 1 -d:` 

# get last interesting line number  
ENDR1=`echo "$LINER1" | tail -1 | cut -f 1 -d:` 

# assign 1st segment to variable 
SEGMENT1R1=`head -n $(($STARTR1 - 1)) r1` 

# assign interesting sorted segment to next variable 
SEGMENT2R1=`echo "$LINER1F"|sort` 

# assign last segment to variable 
SEGMENT3R1=`tail -n $(($LENGTHR1 - $ENDR1)) r1` 

# output whole config with sorted segment to file 
echo "$SEGMENT1R1" > r1 
echo "$SEGMENT2R1" >> r1 
echo "$SEGMENT3R1" >> r1 

我希望這可以這樣做的簡單方法,而不這麼多步驟。

+0

你有很好的邏輯映射出來。將其轉換爲'awk'代碼,但在cmd行上列出文件兩次,第一次將計算所有變量,第二次按照您更改的順序將其打印出來。取決於你的awk版本,排序可能是棘手的問題。你可以使用'if(FNR == NR){first time thru} else {2nd time}'來控制正在發生的處理。祝你好運。 – shellter

0

你不告訴我們你想要什麼作爲排序依據,或你想要的分類,或秀我們預期的輸出,所以這是一個猜測,但也許它是或接近你想要的:

$ cat tst.awk 
/crypto isakmp key 6/ { 
    buf[$0] 
    gotBuf = 1 
    next 
} 
gotBuf { 
    PROCINFO["sorted_in"] = "@ind_str_asc" 
    for (line in buf) { 
     print line 
    } 
    gotBuf = 0 
} 
{ print } 

$ awk -f tst.awk file 
123 345 
678 901 
bla bla bla 
ble ble ble 
crypto isakmp key 6 9i42kpfsej09f09j4ofjwiojefiow352okdwofkwkfi address 123.456.789.012 
crypto isakmp key 6 9j4ofjwiojefiow352okdwofkwkfi9i42kpfsej09f0 address 123.456.789.012 
crypto isakmp key 6 kokofeofepokpfowkfpwjeiofjwiojefiow address 123.456.789.012 
crypto isakmp key 6 ofjwiojefiow352okdwofkwkfi9i42kpfsej09f09j4 address 123.456.789.012 
ccc ddd eee 
fff ggg hhh iii 
123 456 

上面使用的GNU awk 4. *爲sorted_in。

+0

只需簡單地排序加密行(沒有附加條件),我已附加輸出。 – mike

+0

沒有「簡單排序」這樣的東西 - 所有東西都按照某些標準和某種順序進行排序。這聽起來像是你想排序整個行,我猜你想按升序排列區分大小寫的字母排序,對吧?我已經更新了我的答案。 –

+0

是按升序排列的字母排序:) - 無論如何,我需要對兩個文件進行排序,以便它們相互匹配,在這種情況下任何排序都可以,因爲它會以相同的方式對兩個文件進行排序。我需要這個來比較這些文件。 – mike