Sed 交换两行

Sed 交换两行,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是一个流编辑器,因此

如何使用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”,因此效果是我们交换了两行

无论要交换的两行之前、之间或之后出现多少行,此脚本都将工作。事实上,如果有多对匹配行,则每对的成员将在整个文件中交换

如您所见,我只在感兴趣的行中键入一个单词,但任何合适的正则表达式都可以