嗨,我想在文件前添加文字。例如,我想将任务添加到todo.txt文件的开头。我知道echo 'task goes here' >> todo.txt,但这会将行添加到文件的末尾(不是我想要的)。

评论

如果没有有效的方法来处理大型文件,请执行以下操作:unix.stackexchange.com/questions/87772/…

@请您看看此方法superuser.com/a/1352628/11116

#1 楼

Linux:
echo 'task goes here' | cat - todo.txt > temp && mv temp todo.txt


sed -i '1s/^/task goes here\n/' todo.txt


sed -i '1itask goes here' todo.txt

Mac os x:
sed -i '.bak' '1s/^/task goes here\'$'\n/g' todo.txt
echo -e "task goes here\n$(cat todo.txt)" > todo.txt


echo 'task goes here' | cat - todo.txt > temp && mv temp todo.txt


评论


第一个很棒!您介意解释逻辑吗?即时消息不是特别确定如何解释语法。

–user479534
2011-2-18在4:24

@ user8347:将消息(回显“ ...”)传递给cat,该消息使用-(标准输入)作为第一个文件,并将todo.txt作为第二个文件。 cat包含多个文件。将输出(>)发送到名为temp的文件。如果cat没有错误(&&),则将临时文件重命名(mv)回到原始文件(todo.txt)。

–丹尼斯·威廉姆森
2011-2-18在4:51

@itaifrenkel:我得看看你做了什么,但是如果cat收到一个反斜杠n,它将不会将其转换为换行符。其他必须做的。代替cat,尝试用管道传递到hexdump -C中,看看您是否实际上在发送反斜杠和n,或者它是换行符。您也可以尝试使用cat -e显示行尾。

–丹尼斯·威廉姆森
2014年1月26日21:58

使用2和3(对我来说,3似乎更简单)使您可以将文本一次添加到多个文件中。

–费利克斯
2014年1月27日15:24

@Kira:1表示仅在文件的第一行执行下一个命令,并且插入i命令。在手册页的“地址”部分和“零地址或单地址命令”部分中查找。

–丹尼斯·威廉姆森
2015年10月23日在16:33

#2 楼

在我看来,一个更简单的选项是:

echo -e "task goes here\n$(cat todo.txt)" > todo.txt


之所以有效,是因为在用$(...)覆盖todo.txt之前执行了> todo.txt内部的命令,而其他答案很好用,我发现这更容易记住,因为我每天都使用echo和cat。 todo.txt标志回显将解释它们。将换行符添加到序言字符串中的另一种更容易的方法是...

echo "task goes here
$(cat todo.txt)" > todo.txt


...只需使用换行符。当然,它不再是单线的了,但实际上,以前也不是单线的。如果您要在脚本中执行此操作,并且担心缩进(例如,您要在函数内部执行缩进),则有一些变通办法可以使它仍然很合适,包括但不限于:

echo 'task goes here'$'\n'"$(cat todo.txt)" > todo.txt


此外,如果您担心是否在-e的末尾添加了换行符,请不要使用它们。好吧,倒数第二个除外。这不会弄乱结尾。

评论


我根本没有执行$(...)。

– SCL
13年2月22日在17:10

用双引号而不是单引号可能会更好(或根本没有)。

–ℝaphink
13年5月22日在7:25

-e还会在todo.txt中转换转义序列吗?

–mk12
2013年9月2日在21:23

解决方法yield-> cat:<目标文件名>:输入文件为输出文件...

–在这里
2015年1月9日,2:10

在各个平台上,printf会更加一致,并且通常比echo -e更为流畅

– Peter Berg
18年2月17日在20:10

#3 楼

moreutils有一个很好的工具,称为sponge

echo "task goes here" | cat - todo.txt | sponge todo.txt


它将“吸收” STDIN,然后写入文件,这意味着您不必担心关于临时文件并在其中移动。

可以通过moreutils获得带有许多Linux发行版的apt-get install moreutils,或者可以通过带有brew install moreutils的Homebrew在OS X上获得。

评论


我会去(回声``ble'';猫todo.txt):-)

– Ciro Santilli郝海东冠状病六四事件法轮功
18/12/4在9:37

我将使用tee代替海绵,这在大多数发行版回显中默认为“任务在这里”。猫-todo.txt |发球todo.txt

–Angel115
4月28日17:12



发球区示例不正确askubuntu.com/a/752451

–史蒂芬·潘妮(Steven Penny)
5月1日14:51

@stevenpenny好点。现在我记得为什么我最初不建议这样做。我回到这个答案时,并没有注意到输出文件名与输入文件名相同,这就是为什么在写回之前,需要海绵来缓冲所有文件的原因。

–slhck
5月2日12:07

@ Angel115请参阅上面的评论。

–slhck
5月2日12:08

#4 楼

您可以使用POSIX工具ex

ex a.txt <<eof
1 insert
Sunday
.
xit
eof


https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html

#5 楼

您可以创建一个新的临时文件。

echo "new task" > new_todo.txt
cat todo.txt >> new_todo.txt
rm todo.txt
mv new_todo.txt todo.txt


您也可以使用sedawk。但是基本上发生了同样的事情。

评论


假设您的磁盘空间不足,那么new_todo.txt仅被部分写入。您的解决方案似乎丢失了原始文件。

– NPE
2011-2-17在10:31

谁用完了磁盘空间? ;-)这只是一个简单的例子。

–基思
2011-2-17在10:33

@Keith某人在VM上工作,但并不需要特别大的虚拟驱动器。或有人移动大文件。无论如何,反对这一点的真正理由是目录权限。如果您无权在给定目录中创建新文件,则将在脚本中成功执行的唯一命令是原始文件的rm。

–Parthian Shot
2014年7月1日在20:23

#6 楼

如果文本文件足够小以适合内存,则不必创建一个临时文件来替换它。您可以将它们全部加载到内存中并将其写回到文件中。

echo "$(echo 'task goes here' | cat - todo.txt)" > todo.txt


不可能在不覆盖整个文件的情况下向文件的开头添加行。

评论


只是问一个明显的问题:shell变量的字符数限制在哪里?

– nixda
2013年1月9日在22:59

据我所知,它仅受可用内存量的限制。我已经将超过100MB的变量填入内存。文字= $(cat文件)。但是请务必仅使用文本,因为外壳变量不是二进制干净的mywiki.wooledge.org/BashFAQ/058

– Rucent88
13年1月14日在1:48

#7 楼

您可以使用tee

echo 'task goes here' | cat - todo.txt | tee todo.txt


评论


不,你不能问这个问题/ a / 752451

–史蒂芬·潘妮(Steven Penny)
16年4月11日,0:25

#8 楼

您不能在文件开头插入内容。您唯一可以做的就是替换现有内容或在文件的当前末尾之后追加字节。

对您的问题的任何解决方案都需要在内存或内存中创建一个临时文件(或缓冲区)。

请注意,如果在此过程中文件系统碰巧已满,则在创建新文件时不要通过保留原始文件丢失数据。例如:

cat <(echo task go there) todo.txt > todo.txt.new && mv todo.txt.new todo.txt


评论


欢迎下降投票者解释其动机。其余的答案,包括已接受的答案,都没有与我的答复相抵触。

– jlliagre
16年4月12日在13:13

这很难解析,因为<...>看起来像括号,我认为它们不是。 <和(之间的空格可能会有所帮助吗?

– dumbledad
18年6月1日在9:20

这对我不起作用。 echo HOME = \“ / g / Users / timregan / \” | cat-'F:\ Program Files \ Git \ etc \ profile'有效,但是cat
– dumbledad
18年6月1日在9:35

@dumbledad您正在考虑我的答复。您没有任何内容可以解析。 <和(之间的空格将破坏语法。试试cat <(echo HOME = \“ / g / Users / timregan / \”)'F:\ Program Files \ Git \ etc \ profile'

– jlliagre
18年6月2日,1:11

#9 楼

Git Bash + Windows 10 +多行:

这是一个允许您使用多行字符串的版本。

##############################################
## This section for demo purpose only,      ##
## So you can save entire file as           ##
## whatever.sh and run it.                  ##
##                                          ##
##############################################
> MY_TARGET_FILE.txt ##Make Or Clear File
echo "[STARTER_CONTENT]" >> MY_TARGET_FILE.txt
##############################################

## Below is main code:

##################################################
TARGET_FILE_VARIABLE="MY_TARGET_FILE.txt"
ADD_TO_HEAD_VARIABLE=$(cat << "HEREDOC_HEAD_TEXT"
//|  +-------------------------------------+   |//
//|  |                                     |   |//
//|  |     MESSAGE_FOR_HEAD_OF_FILE        |   |//
//|  |                                     |   |//
//|  +-------------------------------------+   |//
HEREDOC_HEAD_TEXT
)
##################################################
TAR=$TARGET_FILE_VARIABLE                       ##
TEX=$ADD_TO_HEAD_VARIABLE                       ##
echo "$TEX" | cat - $TAR > TEMP && mv TEMP $TAR ##
##################################################

## Expected contents of MY_TARGET_FILE.txt :
## //|  +-------------------------------------+   |//
## //|  |                                     |   |//
## //|  |     MESSAGE_FOR_HEAD_OF_FILE        |   |//
## //|  |                                     |   |//
## //|  +-------------------------------------+   |//
## [STARTER_CONTENT]


#10 楼

最终答案

cat <<< "prepended text
$(cat test.txt)" > test.txt


上下文

我对答案不太满意,因为他们觉得打字太多了。我喜欢约翰·艾伯茨(John Alberts)的回答,但无法忍受键入-e。不幸的是,我不小心还翻了约翰·阿尔伯茨(John Alberts)的echo 2衬纸(大大降低了此答案的价值,我在周围玩了30分钟,但哦,确实如此)。

无论如何,我都专注于寻找一些意味着您只需要键入要添加的文件名和文本的内容。

此外,我正在寻找看起来美观的东西。我的意思是:前置符需要物理显示,即使是幻觉也可能会产生助记符。它们减少了认知压力(即,键入3次<不需要太多的思考能力)。

我用单词test.txt创建了文件"monkeys"

,我键入了:

cat <<< "prepend
> $(< test.txt)"


输出:

prepend
monkeys


一点点澄清:

您需要自己手动按enter

在第二行>来自外壳本身,您无需键入。

注意:

(1)我无法管理的是一个衬板。似乎没有可以使用$()\n的herestring组合。这就是为什么您需要自己手动按换行符的原因。
(2)$(< test.txt)$(cat test.txt)具有相同的作用。 《 Bash参考手册》指出:


命令替换$(cat file)可以替换为等效的
,但是更快。$(< file)。也可以这样做:

cat <<< "prepend
> $(cat test.txt)"


更多的打字方式,但是我承认,由于cat被两次打字且比Bash的技巧更为人所知,因此认知压力也有所减轻。参考手册。