简体   繁体   English

使用awk或sed对以pattern开头的行进行排序

[英]sort rows starting with pattern using awk or sed

I'd like to print router configuration and sort only lines starting with pattern crypto isakmp key 6 . 我想打印路由器配置并仅对以pattern crypto isakmp key 6开头的行进行排序。

The important thing is that I want to leave that lines in same place so all lines before and after these lines should stay in same place and order (not sorted). 重要的是,我要将这些行留在同一位置,因此这些行之前和之后的所有行应保持在相同的位置和顺序(未排序)。

Example input file: 输入文件示例:

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

So first I'd like to print unchanged ( random count of rows ): 所以首先我想打印不变(行的随机计数):

123 345
678 901
bla bla bla
ble ble ble

Then I want to print SORTED lines starting with crypto isakmp key 6. 然后我想打印以crypto isakmp key 6开头的SORTED行。

At the end I'd like to print rest of file unchanged (also random count of rows): 最后,我想打印其余的文件(不包括行数):

ccc ddd eee
fff ggg hhh iii
123 456

I've managed this by many operations including getting first and last position of crypto isakmp key 6 and using tail / head commands but it's quite complicated and I wonder if there is option in AWK/SED maybe other linux tool to manage it for specified lines. 我已经通过许多操作来管理此问题,包括获取crypto isakmp key 6第一个和最后一个位置以及使用tail / head命令,但是这非常复杂,我想知道AWK / SED中是否有其他选项也许可以通过Linux工具来管理指定行。 Please explain what your command does in steps. 请分步说明您的命令的作用。

Expected output (crypto sorted rest intact): 预期输出(加密排序的其余部分完整无缺):

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

Don't fully understand what you mean by sorted but this will sort the crypto lines alphabetically and leave the others as they are 不完全理解排序的含义,但这会按字母顺序对加密行进行排序,而使其他行保持原样

Required GNU awk for the asort function. Asort函数所需的GNU awk。

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

Explanation 说明

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'

With meaningful names 具有有意义的名称

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

Here is what I did: 这是我所做的:

# 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

I hope this might be done simple way without so many steps. 我希望这可以通过简单的方法完成而无需太多步骤。

You don't tell us what you want to sort on, or how you want it sorted, or show us the expected output so this is a guess but maybe it is or is close to what you want: 您没有告诉我们您要排序的内容,或如何对其进行排序,也没有告诉我们预期的输出,所以这只是一个猜测,但也许与您想要的或接近的是:

$ 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

The above used GNU awk 4.* for sorted_in. 上面使用了GNU awk 4. *作为sorted_in。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM