我想要打印路由器configuration,只sorting以“crypto isakmp key 6”开头的行。 重要的是,我想在同一个地方留下那些行,所以在这行之前和之后应该保持在同一个地方(不sorting)。
示例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行开始encryptionisakmp键6。
最后,我想打印其余的文件不变(也随机计数的行):
ccc ddd eee fff ggg hhh iii 123 456
我已经通过许多操作来pipe理这个操作,包括获得“crypto isakmp key 6”的第一个和最后一个位置以及使用tail / head命令,但是它非常复杂,我不知道AWK / SED中是否有其他的Linux工具可以pipe理它指定的行。 请解释一下你的命令是怎么做的。
预期的输出(密码sorting完整):
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为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(ie 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 ie 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
你不要告诉我们你想要排序什么,或者你想如何排序,或者向我们展示预期的输出,所以这是一个猜测,但也许它是或接近你想要的:
$ 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。
这是我做的:
# 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
我希望这可以做简单的方法没有太多的步骤。