如何在文件开头插入文本?


213

到目前为止,我已经能够找到如何在文件的开头添加一行,但这并不是我想要的。我会在一个例子中展示

档案内容

some text at the beginning

结果

<added text> some text at the beginning

类似,但是我不想用它创建任何新行...

sed如果可能,我想这样做。


这里有什么适合您的吗?stackoverflow.com/questions/54365/…-无需使用sed
wkl 2012年

Answers:


314

sed 可以在一个地址上运行:

$ sed -i '1s/^/<added text> /' file

1s您在这里的每个答案中看到的神奇之处是什么?线路寻址!

要添加<added text>前10行吗?

$ sed -i '1,10s/^/<added text> /' file

或者您可以使用Command Grouping

$ { echo -n '<added text> '; cat file; } >file.new
$ mv file{.new,}

67
要实际插入新行:sed
-i'1s

1
为什么使用-i?在人身上,它说是后缀。linux.die.net/man/1/sed
endrigoantonini 2015年

-i代表就地,您可以在-i后面添加后缀以进行复制而不是覆盖。-i.new将创建一个以.new结尾的新文件,但是-i将直接编辑该文件。
杰·卡马特

3
请注意,sed不能在空文件上工作-使用0长度输入根本无法使afaict sed做任何事情。
jthill 2015年

2
该解决方案的缺陷在于,如果文件为空,则不会添加文本。
DBedrenko '16

41

如果要在文件的开头添加一行,则需要\n在上述最佳解决方案中的字符串末尾添加。

最好的解决方案是添加字符串,但使用字符串,则不会在文件末尾添加一行。

sed -i '1s/^/your text\n/' file

27

如果文件只有一行,则可以使用:

sed 's/^/insert this /' oldfile > newfile

如果超过一行。之一:

sed '1s/^/insert this /' oldfile > newfile
sed '1,1s/^/insert this /' oldfile > newfile

我已经包括了后者,以便您知道如何进行行的范围调整。两者都用您要插入的文本“替换”了受影响行上的起始行标记。您还可以(假设您sed足够现代)使用:

sed -i 'whatever command you choose' filename

进行就地编辑。


11

您可以使用 cat -

printf '%s' "some text at the beginning" | cat - filename

6
这只会输出文本,后跟文件的内容,但根本不会修改文件。
阿达芬2015年

这是一个很好的解决方案,我想知道为什么它没有得到任何支持。这是我的好先生。另外,为什么要用printf而不是简单的echo呢?
ychaouche 2015年

1
@ychaouche-大概是因为没有可移植的方式来防止echo添加换行符?
Toby Speight

我尝试通过附加> file到命令将其定向到文件中,它对我的​​终端发送了垃圾邮件"some text at the beginning"
theonlygusti

2
printf '%s' "some text" | cat - filename > tmpfile && mv tmpfile filename
luca

10

要仅插入换行符:

sed '1i\\'


5

请注意,在OS X上sed -i <pattern> file失败。但是,如果提供了备份扩展名sed -i old <pattern> file,则filefile.old创建时会对其进行修改。然后file.old,您可以在脚本中删除。


4
或sed -i''文件。然后,它将仅就地编辑而不进行备份。
哈夫(Harv)2015年

我发现macOS sed希望在不创建备份的情况下在适当位置编辑点:sed -i。<pattern>文件
Bryan

4

问题:在文件顶部用父目录的基本名称标记文件。

即,对于

/mnt/Vancouver/Programming/file1

标签的顶部file1Programming

解决方案1-非空文件:

bn=${PWD##*/}    ## bn: basename

sed -i '1s/^/'"$bn"'\n/' <file>

1s 将文本放在文件的第1行。

解决方案2-空文件或非空文件:

sed上面的命令在空文件上失败。这是一个基于/superuser/246837/how-do-i-add-text-to-the-beginning-of-a-file-in-bash/246841#246841的解决方案

printf "${PWD##*/}\n" | cat - <file> > temp && mv -f temp <file>

请注意,-cat命令中的是必需的(读取标准输入:man cat有关更多信息,请参见)。我相信在这里,需要将printf语句的输出(发送至STDIN),并将该文件和该文件转换为temp ...另请参见http://www.linfo.org/cat底部的说明.html

我还添加-fmv命令,以避免在覆盖文件时被要求确认。

要遍历目录:

for file in *; do printf "${PWD##*/}\n" | cat - $file > temp && mv -f temp $file; done

还要注意,这将打破带有空格的路径;还有其他解决方案(例如文件遍历或find . -type f ...-type解决方案)。

附录: 回复:我的最后一条评论,该脚本将允许您在路径中带有空格的目录上递归:

#!/bin/bash

## /programming/4638874/how-to-loop-through-a-directory-recursively-to-delete-files-with-certain-extensi

## To allow spaces in filenames,
##   at the top of the script include: IFS=$'\n'; set -f
##   at the end of the script include: unset IFS; set +f

IFS=$'\n'; set -f

# ----------------------------------------------------------------------------
# SET PATHS:

IN="/mnt/Vancouver/Programming/data/claws-test/corpus test/"

# /superuser/716001/how-can-i-get-files-with-numeric-names-using-ls-command

# FILES=$(find $IN -type f -regex ".*/[0-9]*")        ## recursive; numeric filenames only
FILES=$(find $IN -type f -regex ".*/[0-9 ]*")         ## recursive; numeric filenames only (may include spaces)

# echo '$FILES:'                                      ## single-quoted, (literally) prints: $FILES:
# echo "$FILES"                                       ## double-quoted, prints path/, filename (one per line)

# ----------------------------------------------------------------------------
# MAIN LOOP:

for f in $FILES
do

  # Tag top of file with basename of current dir:
  printf "[top] Tag: ${PWD##*/}\n\n" | cat - $f > temp && mv -f temp $f

  # Tag bottom of file with basename of current dir:
  printf "\n[bottom] Tag: ${PWD##*/}\n" >> $f
done

unset IFS; set +f

3

嗨,回车:

sed -i '1s/^/your text\n/' file



3

只是为了好玩,这里有一个解决方案ed,它不存在无法处理空文件的问题。您可以像对待该问题的任何其他答案一样,将其放入shell脚本中。

ed Test <<EOF
a

.
0i
<added text>
.
1,+1 j
$ g/^$/d
wq
EOF

上面的脚本将要插入的文本添加到第一行,然后连接第一行和第二行。为了避免ed因无效的连接而错误退出,它首先在文件末尾创建一个空行,然后在该行仍然存在的情况下将其删除。

局限性:如果该脚本<added text>正好等于一个句点,则此脚本不起作用。


2

我的两分钱:

sed  -i '1i /path/of/file.sh' filename

即使包含正斜杠的字符串也可以使用 "/"


1
echo -n "text to insert " ;tac filename.txt| tac > newfilename.txt

第一个tac将文件向后传递(最后一行在后),因此“要插入的文本”最后出现。2nd tac再次包装它,因此插入的行在开头,原始文件按其原始顺序排列。


1
您能否解释一下这将如何帮助Tomas解决该问题?
John Odom 2015年

tac | tac-那就是不可扩展的心态形成的方式:-(
Michael Shigorin

0

别名的另一种解决方案。添加到您的init rc / env文件中:

addtail () { find . -type f ! -path "./.git/*" -exec sh -c "echo $@ >> {}" \; }
addhead () { find . -type f ! -path "./.git/*" -exec sh -c  "sed -i '1s/^/$@\n/' {}" \; }

用法:

addtail "string to add at the beginning of file"
addtail "string to add at the end of file"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.