首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用awk或sed对以模式开始的行进行排序

使用awk或sed对以模式开始的行进行排序
EN

Stack Overflow用户
提问于 2015-11-25 10:31:16
回答 3查看 1.1K关注 0票数 2

我想打印路由器配置和排序仅行开始模式crypto isakmp key 6

重要的是,我想把这些行放在同一个地方,所以在这些行之前和之后的所有行都应该保持相同的位置和顺序(而不是排序)。

示例输入文件:

代码语言:javascript
复制
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

因此,首先,我想打印不变的(行的随机计数):

代码语言:javascript
复制
123 345
678 901
bla bla bla
ble ble ble

然后,我想打印排序行,从密码isakmp键6开始。

最后,我想不做改动地打印文件的其余部分(也可以随机计数行):

代码语言:javascript
复制
ccc ddd eee
fff ggg hhh iii
123 456

我通过许多操作(包括获得crypto isakmp key 6的第一位和最后位置)和使用tail / head命令来完成这一任务,但这非常复杂,我想知道在AWK/SED中是否有其他linux可以对指定行进行管理。请分步骤解释你的命令是怎么做的。

预期输出(完整的加密排序rest ):

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-11-25 10:42:21

不完全理解你所说的排序是什么意思,但这将按字母顺序排列密码行,并保留其他行的原样。

所需的GNU awk的asort功能。

代码语言:javascript
复制
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

解释

代码语言:javascript
复制
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'

有意义的名字

代码语言:javascript
复制
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
票数 3
EN

Stack Overflow用户

发布于 2015-11-25 10:31:16

以下是我所做的:

代码语言:javascript
复制
# 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
EN

Stack Overflow用户

发布于 2015-11-25 14:18:51

您没有告诉我们您想要排序的内容,也没有告诉我们预期的输出,所以这只是猜测,但可能是或接近您想要的结果:

代码语言:javascript
复制
$ 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 4.*用于sorted_in。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33914124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档