我必须在文件倒数第二行-file.txt上用“字符串”替换“模式”。
下面的三个sed命令能够打印倒数第二行。但是我需要用“字符串”替换“模式”。有帮助吗?

sed -e '$!{h;d;}' -e x file.txt

sed -n 'x;$p' file.txt

sed 'x;$!d' file.txt

$ cat file.txt
cabbage
spinach
collard greens
corn salad
Sweet pepper
kale

如何替换文件的倒数第二行(甜椒):
一种。如果倒数第二行包含“甜椒”,则用“绿色”替换“甜”
b。用“胡萝卜”代替整行,无论其中包含什么

最佳答案

仅在倒数第二行将Sweet更改为Green,但前提是该行包含Sweet pepper:

$ sed 'x; ${/Sweet pepper/s/Sweet/Green/;p;x}; 1d' file.txt
cabbage
spinach
collard greens
corn salad
Green pepper
kale

要将倒数第二行的全部内容替换为胡萝卜,无论其内容如何,​​请使用以下代码:
$ sed 'x; ${s/.*/carrots/;p;x}; 1d' file.txt
cabbage
spinach
collard greens
corn salad
carrots
kale

这个怎么运作

让我们使用此命令并一次检查一次:
sed 'x; ${s/.*/carrots/;p;x}; 1d'
  • x
    这将交换模式空间(保留最近读取的行)和保留空间。

    完成此操作后,保留空间将包含最近读取的行,而模式空间将包含前一行。
    (异常(exception)是当我们刚刚阅读第一行时。在这种情况下,保留空间将具有第一行,而模式空间将为空。)
  • ${s/.*/carrots/;p;x}
    当我们在最后一行(由$指示)时,模式空间将保留倒数第二行,并且我们可以执行所需的任何替换或其他命令。完成后,我们使用p打印倒数第二行。最后,我们交换模式并再次使用x保留空间,以便模式空间再次包含最后一行。 sed将打印此内容,因为默认情况下,在命令末尾,sed会打印模式空间中的所有内容。
  • 1d
    当我们在第一行(由1指示)时,patten空间为空(因为没有上一行),我们将其删除(d)。

  • 仍然更简单的方法

    此方法易于理解,但执行速度较慢:
    $ tac file.txt | sed '2 {/Sweet pepper/s/Sweet/Green/}' | tac
    cabbage
    spinach
    collard greens
    corn salad
    Green pepper
    kale
    

    而且,对于胡萝卜:
    $ tac file.txt | sed '2 s/.*/carrots/' | tac
    cabbage
    spinach
    collard greens
    corn salad
    carrots
    kale
    

    工作原理:在这里,我们使用tac反转行的顺序。观察:
    $ tac file.txt
    kale
    Sweet pepper
    corn salad
    collard greens
    spinach
    cabbage
    

    这样,倒数第二行即成为第2行。因此,我们只是简单地告诉sed在第2行进行运算。随后,我们再次使用tac来按正确的顺序放置行。

    10-06 02:37