Sed 交换两行
如何使用sedSed 交换两行,sed,Sed,如何使用sedH、H、x、g、g等命令交换两行 例如在文件中 START this is a dog this is a cat this is something else END 假设我想把“这是一只狗”换成“这是别的东西” 这就是我到目前为止所做的: /this is a dog/{ h # put to hold space } /this is something else/{ # now i am stuck on what to do. } 由于sed是一个流编辑器,因此
H
、H
、x
、g
、g
等命令交换两行
例如在文件中
START
this is a dog
this is a cat
this is something else
END
假设我想把“这是一只狗”换成“这是别的东西”
这就是我到目前为止所做的:
/this is a dog/{
h # put to hold space
}
/this is something else/{
# now i am stuck on what to do.
}
由于sed
是一个流编辑器,因此不能用未来行的内容替换当前行。但是,您可以做相反的操作,用您已经看到的行替换未来的行,这就是我的脚本所做的
也许另一种方法是使用
N
命令将每一行追加到模式空间,然后执行两个s
命令交换两个文本字符串。如果您知道要交换的两行中每一行的模式,但不知道行的全部内容,则可以执行以下操作:
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
^this is a cat\Nthis is a dog$
替换模式将“dog”保留在累积行的末尾。它不断地交换最后两行,我们保持在保持空间中,这样“狗”就会“泡泡”到底
例如,让我们在“cat”行之后再放一行,这样过程就更清晰了。我们将忽略“dog”之前和“something”之后的行。我将继续使用我的昵称来引用这些行
this is a dog
this is a cat
there's a bear here, too
this is something else
先读“狗”,然后取“猫”。完成了一些附加和交换。现在模式空间看起来是这样的(\N
代表一个换行符,我使用大写字母“N”,因此它很突出,^
是模式空间的开始,$
是结束):
substitution命令查找任何数量的非换行字符(并捕获它们),后跟一个换行符,后跟任何数量的非换行字符(并捕获它们),这些字符位于换行符($)的末尾,并用两个捕获的字符串以换行符分隔的相反顺序替换所有字符。现在,模式空间如下所示:
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
^this is a cat\Nthis is a dog$
现在我们交换并阅读一行新词。这不是什么“东西”,所以我们做了一些附加和交换,现在我们有:
^this is a cat\Nthis is a dog\Nthere's a bear here, too$
我们再次进行替换,得到:
^this is a cat\Nthere's a bear here, too\Nthis is a dog$
我们为什么不改成“熊/狗/猫”?因为由两行组成的正则表达式模式(通常,每行由非新行和一个新行组成)使用$
锚定在行的末尾,所以我们忽略了它前面的任何内容。请注意,最后一个换行符是隐含的,实际上不存在于模式或保持空间中。这就是为什么我不在这里展示它
现在我们读“某物”并打印出来。我们交换。嘿有些东西我们一直在“冒泡”。分支和打印。由于“dog”位于行的底部(已在保留空间中累积),并且我们在该行之前打印了“something”,因此效果是我们交换了两行
无论要交换的两行之前、之间或之后出现多少行,此脚本都将工作。事实上,如果有多对匹配行,则每对的成员将在整个文件中交换
如您所见,我只在感兴趣的行中键入一个单词,但任何合适的正则表达式都可以