Làm cách nào để thêm văn bản vào đầu tệp trong Bash?


285

Xin chào Tôi muốn thêm văn bản vào một tập tin. Ví dụ: tôi muốn thêm các tác vụ vào đầu tệp todo.txt. Tôi biết echo 'task goes here' >> todo.txtnhưng điều đó thêm dòng vào cuối tập tin (không phải những gì tôi muốn).


2
Nếu không có cách nào hiệu quả để làm điều đó cho các tệp lớn: unix.stackexchange.com/questions/87772/ Kẻ
Ciro Santilli 改造 改造 改造 事件

@ bạn có thể xem phương pháp này superuser.com/a/1352628/11116
Evan Carroll

Câu trả lời:


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

hoặc là

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

hoặc là

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

4
cái đầu tiên hoạt động tuyệt vời! bạn có phiền giải thích logic không? tôi không đặc biệt chắc chắn làm thế nào để giải thích cú pháp.
dùng479534

44
@ user8347: ống ( |) thông báo ( echo '...') catsử dụng -(đầu vào tiêu chuẩn) làm tệp đầu tiên và todo.txtlàm tệp thứ hai. catconCATenates nhiều tập tin. Gửi đầu ra ( >) đến một tệp có tên temp. Nếu không có lỗi ( &&) từ catđó đổi tên ( mv) temptệp trở lại tệp gốc ( todo.txt).
Dennis Williamson

1
@itaifrenkel: Tôi sẽ phải xem những gì bạn đã làm, nhưng nếu catnhận được một dấu gạch chéo ngược theo nghĩa đen, nó sẽ không chuyển đổi nó thành một dòng mới. Một cái gì đó khác phải làm điều đó. Thay vì cat, hãy thử chuyển sang hexdump -Cxem bạn có thực sự gửi dấu gạch chéo ngược và n hoặc nếu đó là một dòng mới. Bạn cũng có thể thử cat -ehiển thị kết thúc dòng.
Dennis Williamson

1
Sử dụng 2 và 3 (3 có vẻ đơn giản hơn đối với tôi) cho phép bạn thêm văn bản vào nhiều tệp cùng một lúc.
Felix

4
@Kira: Có 1nghĩa là chỉ thực hiện lệnh tiếp theo trên dòng một của tệp và ilệnh được chèn. Tìm trong trang man trong phần "Địa chỉ" và trong phần "Lệnh không hoặc một địa chỉ".
Dennis Williamson

73

Một lựa chọn đơn giản hơn theo ý kiến ​​của tôi là:

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

Điều này hoạt động vì lệnh bên trong $(...)được thực thi trước đó todo.txtđược ghi đè bằng> todo.txt

Trong khi các câu trả lời khác hoạt động tốt, tôi thấy điều này dễ nhớ hơn nhiều vì tôi sử dụng tiếng vang và tiếng mèo mỗi ngày.

EDIT: Giải pháp này là một ý tưởng rất tồi nếu có bất kỳ dấu gạch chéo ngược nào todo.txt, bởi vì -etiếng vang cờ sẽ giải thích chúng. Một cách khác, dễ dàng hơn nhiều để đưa dòng mới vào chuỗi lời nói đầu là ...

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

... chỉ đơn giản là sử dụng dòng mới. Chắc chắn, nó không còn là một lớp lót nữa, nhưng thực tế nó cũng không phải là một lớp lót trước đó. Nếu bạn đang thực hiện điều này trong một tập lệnh và lo lắng về việc thụt lề (ví dụ: bạn đang thực hiện điều này bên trong một chức năng), có một vài cách giải quyết để làm cho điều này vẫn phù hợp, bao gồm nhưng không giới hạn ở:

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

Ngoài ra, nếu bạn quan tâm đến việc liệu một dòng mới có được thêm vào cuối hay không todo.txt, đừng sử dụng những dòng này. Chà, ngoại trừ cái thứ hai đến cái cuối cùng. Điều đó không gây rối với kết thúc.


1
Tôi hoàn toàn không nhận được $ (...).
SCL

2
Điều đó có thể hoạt động tốt hơn (hoặc hoàn toàn) với dấu ngoặc kép thay vì đơn lẻ
ℝaphink

5
Không phải -ecũng chuyển đổi các chuỗi thoát bên trong todo.txt?
mk12

2
Năng suất giải pháp -> cat: <tên tệp đích>: tệp đầu vào là tệp đầu ra ...
trong

printf sẽ phù hợp hơn rất nhiều trên các nền tảng và thường hoạt động trơn tru hơn echo -e
Peter Berg

28

moreutilsmột công cụ tốt gọi là sponge:

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

Nó sẽ "ngâm" STDIN và sau đó ghi vào tệp, điều đó có nghĩa là bạn không phải lo lắng về các tệp tạm thời và di chuyển chúng xung quanh.

Bạn có thể nhận được moreutilsnhiều bản phân phối Linux, thông qua apt-get install moreutilshoặc trên OS X bằng Homebrew , với brew install moreutils.


Tôi sẽ đi cho (echo 'ble'; cat todo.txt):-)
Ciro Santilli 改造 心 心

11

Bạn có thể sử dụng Vim trong chế độ Ex:

ex -s -c '1i|task goes here' -c x todo.txt
  1. 1 chọn dòng đầu tiên

  2. i chèn

  3. x lưu và đóng


5

Bạn có thể tạo một tập tin mới, tạm thời.

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

Bạn cũng có thể sử dụng sedhoặc awk. Nhưng về cơ bản điều tương tự xảy ra.


1
Giả sử bạn hết dung lượng đĩa để chỉ new_todo.txtđược ghi một phần. Giải pháp của bạn dường như mất tập tin gốc.
NPE

Ai hết dung lượng đĩa? ;-) Đó chỉ là một ví dụ đơn giản.
Keith

2
@Keith Một người nào đó làm việc trên máy ảo không mong muốn cần một ổ đĩa ảo đặc biệt lớn. Hoặc ai đó di chuyển một tập tin lớn. Trong mọi trường hợp, đối số thực sự chống lại điều này là quyền thư mục; nếu bạn không có quyền tạo các tệp mới trong thư mục đã cho, lệnh duy nhất sẽ thực hiện thành công trong tập lệnh của bạn là rmtệp gốc.
Bắn Parthian

3

Nếu tệp văn bản đủ nhỏ để vừa trong bộ nhớ, bạn không phải tạo tệp tạm thời để thay thế. Bạn có thể tải tất cả vào bộ nhớ và ghi lại vào tệp.

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

Không thể thêm dòng vào đầu tệp mà không ghi quá toàn bộ tệp.


Chỉ cần đặt câu hỏi rõ ràng: giới hạn ký tự của các biến shell ở đâu?
nixda

Theo như tôi biết, nó chỉ bị giới hạn bởi số lượng bộ nhớ khả dụng. Tôi đã điền đầy đủ hơn 100 MB vào bộ nhớ. text=$(cat file). Hãy cẩn thận chỉ sử dụng văn bản, bởi vì các biến shell không phải là nhị phân sạch mywiki.wooledge.org/BashFAQ/058
Rucent88

2

Bạn không thể chèn nội dung ở đầu tệp. Điều duy nhất bạn có thể làm là thay thế nội dung hiện có hoặc chắp thêm byte sau khi kết thúc tập tin hiện tại.

Bất kỳ giải pháp nào cho câu hỏi của bạn sau đó yêu cầu một tệp tạm thời (hoặc bộ đệm) được tạo (trên bộ nhớ hoặc trên đĩa) mà cuối cùng sẽ ghi đè lên tệp gốc.

Cảnh giác với việc không mất dữ liệu bằng cách bảo quản tệp gốc trong khi tạo tệp mới, nếu hệ thống tệp xảy ra đầy trong quá trình. ví dụ:

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

Downvoters được chào đón để giải thích động lực của họ. Không có câu trả lời nào còn lại, kể cả câu trả lời được chấp nhận, không mâu thuẫn với câu trả lời của tôi.
jlliagre

Điều này rất khó để phân tích vì <...> trông giống như dấu ngoặc, mà tôi cho rằng chúng không phải. Khoảng cách giữa <và (có thể giúp?
dumbledad

Điều này không làm việc cho tôi. echo HOME=\"/g/Users/timregan/\" | cat - 'F:\Program Files\Git\etc\profile'hoạt động nhưng cat <echo HOME=\"/g/Users/timregan/\" 'F:\Program Files\Git\etc\profile'đưa ra lỗi "echo: Không có tệp hoặc thư mục như vậy"
dumbledad

@dumbledad Bạn đang xem lại câu trả lời của tôi. Không có gì để bạn phân tích trong đó. Một khoảng trắng giữa <(sẽ phá vỡ cú pháp. Hãy thửcat <(echo HOME=\"/g/Users/timregan/\") 'F:\Program Files\Git\etc\profile'
jlliagre


0

GitBash + Windows10 + Đa tuyến :

Đây là phiên bản cho phép bạn sử dụng chuỗi nhiều dòng .

##############################################
## 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]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.