如何在文件中添加多行

如何在文件中添加多行

在问题中如何将多行追加到文件中OP 正在寻找一种将多行附加到 shell 内的文件的方法。解决方案:

cat <<EOT >> test.txt
line 1
line 2
EOT

我想在前面添加行,我的尝试如下所示:

echo 3 >test.text
cat test.text <<EOT >> test.text
1
2
EOT

但这会导致错误:

cat: test.text: input file is output file

编辑:为了澄清起见,我正在遵循一份很长的服务器设置指南,其中包含手动编辑配置文件的说明。编辑有时涉及将文本块添加到文件中。在自动化某些步骤时,我想通过按原样复制指南中的文本并将其放入 bash 单行代码中来保留命令的冗长性。因此,EOT首选使用多行文本输入。

编辑:使用 sed 的其他答案要求将反斜杠附加到每行的末尾,但我想输入多行而不进行修改。

有没有办法以与上面类似的方式在文件前面添加多行(理想情况下没有临时文件和安装moreutils)?

答案1

最安全的方法是将原始文件复制到临时位置,并将新内容与该文件连接到旧名称中:

tmpfile=$(mktemp)

cp myfile "$tmpfile" &&
cat - "$tmpfile" <<NEW_CONTENTS >myfile
this is
new contents
at top of file
NEW_CONTENTS

rm "$tmpfile"

请注意,cat命令本身是几乎和你的一样

cat myfile <<EOT >>myfile
1
2
3
EOT

但是,cat必须告诉它还读取其标准输入,当其文件名操作数之一是 时,它会执行此操作-。我们也无法从原始文件重定向,然后将结果附加到同一个文件,因为这会创建一个循环,使文件不断增长,直到填满分区上的所有空间。这就是为什么我首先将文件复制到临时文件,然后使用它为旧名称创建新内容。

我们也可以这样做

tmpfile=$(mktemp)

cat - myfile <<NEW_CONTENTS >"$tmpfile" &&
this is
new contents
at top of file
NEW_CONTENTS
mv "$tmpfile" myfile

即,将结果写入临时文件,然后移动它以替换原始文件。但是,此操作顺序不能保证保留 的所有权和权限myfile


一个小型 shell 函数,它接受标准输入并将其放置在给定文件名的顶部:

paste_header () {
    local tmpfile=$(mktemp)

    trap "rm -f '$tmpfile'" EXIT

    cat - "$1" >"$tmpfile" &&
    cat "$tmpfile" >"$1"
}

例如,这种编写方式允许用户以交互方式粘贴剪贴板中的内容,但如果输入被 中断,则不会修改原始文件Ctrl+C。交互式输入需要通过按Ctrl+D(发送EOT,即文本结束)来终止。

该函数将用作

paste_header filename

以交互方式粘贴要添加到的数据filename(以 结束输入Ctrl+D)。

或者

paste_header filename <otherfile

从另一个文件插入数据。

答案2

如果您需要读取命令的输出,您可以使用ed链接问题中的方法,并进行以下变体:

ed -s test.txt <<< $'0r !echo stuff\nw\nq'

r会将命令的输出echo stuff写入test.txt零行之后。


要通过here-doc在第一行之前插入多行文本,您需要运行

ed -s test.txt <<EOT
1i
add some line
and some more
to the beginning
.
w
q
EOT

该点表示输入模式的结束,这意味着最后一个解决方案假设您的文本不包含由单个点组成的行。

答案3

你可以使用普通的 ol'前文本编辑器它应该在几乎所有 POSIX 兼容系统中可用。

要插入第一行,只需执行以下操作

ex -sc '1i|new first line' -cx test.txt

对于要添加多行的情况,只需在循环中添加行,最后添加最上面的元素(就像堆栈一样)

for number in 5 4 3 2 1; do
    ex -sc '1i|'"$number"'' -cx newfile
done

of 如果想避免对文件进行多次写操作,则将多行内容构造一个变量,直接插入

multiple_lines=$'line1\nline2\nline3\nline4\nline5\n'
ex -sc '1i|'"$multiple_lines"'' -cx newfile

答案4

使用 sed:

$ sed -e 'i1' -e 'i2' test.text
1
2
3

相关内容