从文件中将文本插入到另一个文件的开头 - bash

9

我正在尝试将一些版权信息插入到一些源文件的开头。我知道可以使用以下方式中的sed:

sed "1iSome copyrighted information." sample.txt

我需要在sample.txt文件的开头插入来自另一个文件的文本,例如"一些版权信息"。在sed中是否有一种方式可以使用cat命令实现上述目的?类似于以下内容:

sed "1i{cat header.txt}" sample.txt

我已经通过谷歌搜索上述内容,但还没有找到我想要的精确答案。非常感谢您的任何帮助。

谢谢。

6个回答

11

很抱歉占用了整个答案 - 只是为了格式化而已 :) 基本上,这是和@tangens相同的答案,但没有使用临时文件:

echo "$(cat header.txt sample.txt)" > sample.txt

请注意双引号(")的使用以保留行尾换行符,同时需要注意cat命令是在子进程中执行,所以不会出现覆盖正在被读取的文件(sample.txt)的情况。

祝好!


10

如果您拥有 GNU sed

sed -i -e '2{x;G};1{h;rheader.txt' -e 'd}' sample.txt

sample.txt必须至少包含两行。

即使头文件中包含sed特殊的字符,此方法也可行。

解释:

  • -i - 原地编辑文件
  • -e - 将脚本分成几个部分 - 在本例中需要这样做来定界头文件名的结尾(它也可以由换行符定界)
  • 1{h; - 在文件的第一行(sample.txt)将其保存到hold space中
  • rheader.txt - 读入头文件(header.txt)
  • d} - 从模式空间中删除原始第一行,并结束第一行的处理 - 在此处删除它可以防止在文件开头插入额外的空行
  • 现在输出头文件内容
  • 2{x; - 当读取文件的第二行(sample.txt)时,将其交换到hold space中,并将hold space(包含原始第一行)交换到模式空间中
  • G} - 将hold space附加到模式空间的末尾(其中现在包含原始第一行和第二行),并完成第二行的处理
  • 现在输出行1和行2,然后继续处理文件的剩余部分,该部分只包括读取和输出每一行。

编辑:我从最初发布的版本中删除了一个多余的命令。


你如何递归地[带有条件]将此应用于文件夹中的所有文件?例如:对于 . 文件夹中的所有子文件夹/文件:如果文件为*.c,则 SED_CMD - bny
@bny:一种方法(适用于Bash 4):shopt -s globstar; for file in ./**/*.c; do [[ -f $file ]] && SED_CMD; done。您将使用"$file"作为传递给sed的文件名参数。如果您使用先前版本的Bash,则可以使用findxargs代替for循环。 - Dennis Williamson

8
使用ed文本编辑器:
echo -e '0r header.txt\nw' | ed sample.txt

或者使用 vi/ex 命令:

vi - +'0r header.txt|wq' sample.txt

但我并没有看到在sed中运行命令的任何方法。


5
cat header.txt sample.txt > temp.txt
mv temp.txt sample.txt

将标题放在示例下方 - ghostdog74
1
这将把sampte.txt附加到header.txt中。顺序是正确的。在您的评论之后,我再次尝试它。它有效。 - tangens
你可以在一行代码中完成这个操作:"cat header.txt sample.txt > temp.txt && mv temp.txt sample.txt"。使用一次后就会非常容易理解。 - Jason R. Mick

1

如果你真的想使用 sed 来做这件事:

INFO=$(cat header.txt)  # read the contents of file headers.txt into var INFO
sed -i "1i$INFO" sample.txt # insert $INFO, use -i to change the file inplace

不过,我会使用基于cat的方法。


1
我认为如果您的标题包含一些sed解释为命令的字符串,那么这种方法可能不起作用。 - tangens
tangens 是正确的,那样是行不通的。header.txt 包含以 C 风格注释(/* 和 */)形式的信息,sed 将其解释为命令。 - Sriram

0

为什么不换个方式呢,比如将你的源文件附加到版权文件中?

'cat' 命令实际上是 'concatenate' 的缩写,你可以简单地说

for f in *.c
do
    cp $f /tmp
    cat copyright.txt /tmp/$f >$f
done

你在 /tmp 目录下面有一个严重的清理问题 - 这还假设你一开始就没有在 /tmp 目录下工作! - Jonathan Leffler
1
不完全是这样,这就是 /tmp 的作用。如果你满意,你只需删除它们,如果你不满意,你可以保证可以撤消更改。 - Gaius

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