題 如何在Bash中將文本添加到文件的開頭?


嗨,我想將文本添加到文件中。例如,我想將任務添加到todo.txt文件的開頭。我知道 echo 'task goes here' >> todo.txt 但是這會將行添加到文件的末尾(而不是我想要的)。


236
2018-02-17 03:21


起源


如果沒有有效的方法為大文件執行此操作: unix.stackexchange.com/questions/87772/... - Ciro Santilli 新疆改造中心 六四事件 法轮功
@你可以看一下這個方法 superuser.com/a/1352628/11116 - Evan Carroll


答案:


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

319
2018-02-17 03:34



第一個很棒!你介意解釋邏輯嗎?我不是特別肯定如何解釋語法。 - user479534
@ user8347:管道(|)消息(echo '...') 至 cat 使用 - (標準輸入)作為第一個文件和 todo.txt 作為第二個。 cat conCATenates多個文件。發送輸出(>)到一個名為的文件 temp。如果沒有錯誤(&&)來自 cat 然後重命名(mv) temp 歸檔到原始文件(todo.txt)。 - Dennis Williamson
我在sed的最後一個例子中不知道這種可能的語法,有人能告訴我這種語法的名稱是什麼,所以我可以搜索更多關於它的內容嗎? - Kira
@Kira:The 1 表示只在文件和第一行上執行下一個命令 i 命令是插入。查看“地址”部分下的手冊頁以及“零地址或單地址命令”部分。 - Dennis Williamson
@Terrance:如果你的 sed 命令看起來像這樣(插入一個前導標籤): '1i\tSome Text',你可能需要加倍反斜杠。否則,你的方言 sed 可能不承認 \t 作為標籤。 - Dennis Williamson


我認為一個更簡單的選擇是:

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

這是因為裡面的命令 $(...) 之前執行 todo.txt 被覆蓋 > todo.txt

雖然其他答案工作正常,但我發現這更容易記住,因為我每天都使用echo和cat。

編輯: 如果有任何反斜杠,這個解決方案是一個非常糟糕的主意 todo.txt,因為謝謝 -e flag echo將解釋它們。另一種更簡單的方法是將新行添加到前言字符串中......

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

......只是使用換行符。當然,它不再是單線,但實際上它之前也不是單線。如果您在腳本中執行此操作,並且擔心縮進(例如,您正在函數內執行此操作),則有一些解決方法可以使其仍然很適合,包括但不限於:

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

此外,如果您關心是否將新行添加到結尾 todo.txt,不要使用這些。好吧,除了倒數第二個。這並沒有弄亂結束。


60
2017-12-19 18:57



我根本沒有執行$(...)。 - SCL
使用雙引號而不是單引號可能更好(或根本)更好... - ℝaphink
不會的 -e 還可以在todo.txt中轉換轉義序列? - mk12
解決方法產量 - > cat:<目標文件名>:輸入文件是輸出文件... - ingyhere
printf在各個平台上會更加一致,並且通常比echo -e更順暢 - Peter Berg


moreutils 有一個很好的工具叫 sponge

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

它將“吸收”STDIN然後寫入文件,這意味著您不必擔心臨時文件並移動它們。

你可以得到 moreutils 通過許多Linux發行版 apt-get install moreutils,或在OS X上使用 家釀,與 brew install moreutils


27
2018-04-22 12:47





您可以在Ex模式下使用Vim:

ex -s -c '1i|task goes here' -c x todo.txt
  1. 1 選擇第一行

  2. i 插入

  3. x 保存並關閉


6
2018-04-11 00:23





您可以創建一個新的臨時文件。

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

你也可以使用 sed 要么 awk。但基本上同樣的事情發生了。


4
2018-02-17 03:26



假設你已經沒有磁盤空間了 new_todo.txt 得到的部分內容。您的解決方案似乎丟失了原始文件。 - NPE
誰沒有磁盤空間? ;-)這只是一個簡單的例子。 - Keith
@Keith有人在VM上工作,他們不希望需要特別大的虛擬驅動器。或者有人移動大文件。無論如何,反對此的真正論據是目錄權限;如果您沒有在給定目錄中創建新文件的權限,那麼將在您的腳本中成功執行的唯一命令是 rm 原始文件。 - Parthian Shot


如果文本文件足夠小以適合內存,則不必創建臨時文件來替換它。您可以將其全部加載到內存中並將其寫回文件。

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

在不寫入整個文件的情況下,無法在文件開頭添加行。


3
2018-01-09 22:49



只是問一個顯而易見的問題: shell變量的字符限制在哪裡? - nixda
據我所知,它僅受可用內存量的限制。我已經將超過100MB的變量填充到內存中。 text=$(cat file)。但是要小心只使用文本,因為shell變量不是二進制清理 mywiki.wooledge.org/BashFAQ/058 - Rucent88


您無法在文件的開頭插入內容。您唯一能做的就是替換現有內容或在文件當前結束後附加字節。

然後,您的問題的任何解決方案都需要創建臨時文件(或緩衝區)(在內存或磁盤上),最終將覆蓋原始文件。

如果文件系統在此過程中碰巧已滿,請注意不要在創建新文件時保留原始文件而丟失數據。例如:

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

2
2018-02-17 06:25



歡迎Downvoters解釋他們的動機。剩下的答案,包括被接受的答案,都沒有在我的答復中與任何內容相矛盾。 - jlliagre
這很難解析,因為<...>看起來像括號,我認為它們不是。 <和之間的空間(可能有幫助嗎? - dumbledad
這不適合我。 echo HOME=\"/g/Users/timregan/\" | cat - 'F:\Program Files\Git\etc\profile' 工作,但 cat <echo HOME=\"/g/Users/timregan/\" 'F:\Program Files\Git\etc\profile' 給出錯誤“echo:沒有這樣的文件或目錄” - dumbledad
@dumbledad你是在想我的回答。你無需解析它。之間的空間 < 和 ( 會破壞語法。嘗試 cat <(echo HOME=\"/g/Users/timregan/\") 'F:\Program Files\Git\etc\profile' - jlliagre


您可以使用 tee

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

0
2017-07-08 14:16



你不能 askubuntu.com/a/752451 - Steven Penny


GitBash + Windows10 + Multline

這是一個允許您使用的版本 多行字符串

##############################################
## 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]

0
2017-08-04 07:04