我怎样才能利用SED的H,h,x,g,G等命令来交换两行呢?
例如在文件中
START
this is a dog
this is a cat
this is something else
END
Run Code Online (Sandbox Code Playgroud)
说我想用"这是别的东西"交换"这是一只狗".
这是我到目前为止:
/this is a dog/{
h # put to hold space
}
/this is something else/{
# now i am stuck on what to do.
}
Run Code Online (Sandbox Code Playgroud)
Pau*_*ce. 22
如果您知道要交换的两行中的每一行上的模式,但不知道行的完整内容,则可以执行以下操作:
sed -n ' # turn off default printing
/dog/{ # if the line matches "dog"
h # put it in hold space
:a # label "a" - the top of a loop
n # fetch the next line
/something/{ # if it matches "something"
p # print it
x # swap hold and pattern space
bb # branch out of the loop to label "b"
} # done with "something"
# if we're here, the line doesn't match "something"
H # append pattern space to hold space
x # swap hold and pattern space
s/\([^\n]*\)\n\([^\n]*\)$/\2\n\1/ # see below
x # swap hold and pattern space
ba # branch to the top of the loop to label "a"
} # done with "dog"
:b # label "b" - outside the loop
# print lines that don't match and are outside the pair
p # also prints what had been accumulating in hold space
' inputfile
Run Code Online (Sandbox Code Playgroud)
替换模式将"狗"保持在累积行的末尾.它不断交换我们保留在空间中的最后两行,以便"狗""气泡"到底部.
例如,让我们在"cat"行之后添加另一行,这样过程就会更加清晰.我们将忽略"狗"之前和"某事"之后的界限.我将继续使用我的昵称来引用这些行
this is a dog
this is a cat
there's a bear here, too
this is something else
Run Code Online (Sandbox Code Playgroud)
读取"狗",然后取出"猫".一些追加和交换已完成.现在模式空间看起来像这样(\N代表换行符,我使用大写"N",因此它突出,它^是模式空间的开始,$是结束):
^this is a dog\Nthis is a cat$
Run Code Online (Sandbox Code Playgroud)
替换命令查找不是换行符(并捕获它们)的任意数量的字符,后跟换行符后跟任意数量的非换行符(并捕获它们)的行,这些符号位于行的末尾($)并替换所有这两个捕获的字符串以相反的顺序由换行符分隔.现在模式空间如下所示:
^this is a cat\Nthis is a dog$
Run Code Online (Sandbox Code Playgroud)
现在我们交换并读取一个新行.它不是"东西"所以我们做一些追加和交换,现在我们有:
^this is a cat\Nthis is a dog\Nthere's a bear here, too$
Run Code Online (Sandbox Code Playgroud)
我们再次进行替换并得到:
^this is a cat\Nthere's a bear here, too\Nthis is a dog$
Run Code Online (Sandbox Code Playgroud)
为什么我们不换"熊/狗/猫"呢?因为由两行组成的正则表达式模式(每个通常由非换行符后跟一个换行符组成)使用它锚定在行的末尾,$所以我们忽略了它之前的任何内容.请注意,最后一个换行是隐含的,并且实际上不存在于模式或保留空间中.这就是为什么我不在这里展示它.
现在我们读"东西"并打印出来.我们交换.嘿! 那些我们一直在"冒泡"的东西.分支和打印.由于"狗"位于线的底部(已经在保留空间中积累)并且我们在那一堆之前打印了"某物",效果是我们交换了两条线.
无论在要交换的两行之前,之间或之后出现多少行,此脚本都将起作用.实际上,如果存在多对匹配行,则每对中的成员将在整个文件中交换.
正如你所看到的,我只关注感兴趣的一行中的一个词,但任何合适的正则表达式都可以.