使用sed如何在文件的第一行插入文本?

11

嗨,我正在尝试使用sed将文本添加到文件的第一行。到目前为止,我已经尝试了:

#!/bin/bash
touch test
sed -i -e '1i/etc/example/live/example.com/fullchain.pem;\' test

这个不起作用,还尝试了

#!/bin/bash
touch test
sed -i "1i ssl_certificate /etc/example/live/example.com/fullchain.pem;" test

这似乎也不起作用了,但奇怪的是当我尝试使用

#!/bin/bash
touch test
echo "ssl_certificate /etc/example/live/example.com/fullchain.pem;" > test

当我使用cat test命令时,第一行文本会出现,但是一旦我键入sed -i "2i ssl_certificate_key /etc/example/live/example.com/privkey.pem;"命令后,我看不到应该在第二行执行的信息,这是ssl_certificate_key /etc/example/live/example.com/privkey.pem;

所以我的问题总结如下:

  1. 可以使用sed将文本插入新创建文件的第一行吗?
  2. 如果可以,最佳的方法是在第一行文本之后插入文本?
5个回答

14

假设您有一个像这样的文件

one
two

接着在第一行后面添加:

$ sed '1 s_$_/etc/example/live/example.com/fullchain.pem;_' file
one/etc/example/live/example.com/fullchain.pem;
two

在第一行前插入:

$ sed '1 i /etc/example/live/example.com/fullchain.pem;' file
/etc/example/live/example.com/fullchain.pem;
one
two
或者,在第一行后面添加:
$ sed '1 a /etc/example/live/example.com/fullchain.pem;' file
one
/etc/example/live/example.com/fullchain.pem;
two
注意那些 `sed` 表达式中的数字 `1`,在 `sed` 的术语中,这被称为地址。它告诉你要操作哪一行上面的 命令
如果你要寻址的文件不包含该行,sed 命令将不会被执行。这就是为什么,如果你的文件为空,就不能在第一行插入/追加内容。
而不是使用 流编辑器(stream editor) 对空文件进行追加操作,只需使用 shell 重定向符号 >>:
echo "content" >> file

1
第一行前置怎么样? - flywire

2
你的问题出在sed无法定位你要写入的行,例如:
touch test
sed -i -e '1i/etc/example/live/example.com/fullchain.pem;\' test

尝试在test的第1行插入内容,但此时该行不存在。如果您创建文件的方式是:
echo -en "\n" > test
sed -i '1i/etc/example/live/example.com/fullchain.pem;\' test

如果你多加一行,程序不会报错,但是会出现额外的空行。同样地,当你调用:

sed -i "2i ssl_certificate_key /etc/example/live/example.com/privkey.pem;"

你告诉 sed 在第二行插入以下数据,但此时该行不存在,因此sed 无法编辑文件。
因此,对于文件的初始行或最后一行,不应使用sed,因为简单的>>>流重定向已经足够。

1

在macOS上使用sed将文本插入到第一行并将其余部分放在新行上,对我而言,以下方法有效:

sed -i '' '1 i \
Insert
' ~/Downloads/File-path.txt

1

如果您确保输入文件至少有一行,则您的命令将起作用:

[ "$(wc -l < test)" -gt 0 ] || printf '\n' >> test
sed -i -e '1 i/etc/example/live/example.com/fullchain.pem;\' test

0

首尾操作

我认为任何搜索如何在文件开头/结尾插入/追加文本的人,可能也需要知道如何进行另一种操作。

cal |                            \
  gsed -E                        \
       -e     '1i\{'             \
       -e     '1i\  "lines": ['  \
       -e 's/(.*)/    "\1",/'    \
       -e '$s/,$//'              \
       -e     '$a\  ]'           \
       -e     '$a\}'

说明

这是将cal输出通过管道传递给gnu-sed(在macOS上安装的gsed通过brew.sh),使用扩展正则表达式(-E)和6个“脚本”应用(-e),并使用\转义换行符以提高可读性。脚本1和2使用1i\来“在第1行插入”。脚本5和6使用$a\来“在最后一行追加”。我垂直对齐文本输出,使代码表示预期结果。脚本3和4进行替换(后者仅适用于“最后一行”)。结果是将命令输出转换为有效的JSON。

输出

{
  "lines": [
    "    October 2019      ",
    "Su Mo Tu We Th Fr Sa  ",
    "       1  2  3  4  5  ",
    " 6  7  8  9 10 11 12  ",
    "13 14 15 16 17 18 19  ",
    "20 21 22 23 24 25 26  ",
    "27 28 29 30 31        ",
    "                      "
  ]
}

如果需要在macOS/BSD版本的sed上运行,请参考我的答案


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接