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


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 nhiệm vụ vào đầu của một tập tin todo.txt. Tôi biết echo 'task goes here' >> todo.txt nhưng điều đó sẽ thêm dòng vào cuối tệp (không phải những gì tôi muốn).


229
2018-02-17 03:21


gốc


Có nếu không có cách hiệu quả để làm điều đó cho các tập tin lớn: unix.stackexchange.com/questions/87772/… - Ciro Santilli 新疆改造中心 六四事件 法轮功
@ bạn có xem xét phương pháp này không superuser.com/a/1352628/11116 - Evan Carroll


Các câu trả lời:


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

305
2018-02-17 03:34



cái đầu tiên hoạt động rất tốt! bạn có thể giải thích logic được không? im không đặc biệt chắc chắn làm thế nào để giải thích cú pháp. - user479534
@ user8347: Ống (|) thông điệp (echo '...') đến cat sử dụng - (đầu vào tiêu chuẩn) làm tệp đầu tiên và todo.txt là thứ hai. cat conCATenates nhiều tập tin. Gửi đầu ra (>) vào một tệp có tên temp. Nếu không có lỗi (&&) từ cat sau đó đổi tên (mv) các temp tập tin trở lại tập tin gốc (todo.txt). - Dennis Williamson
Tôi không biết về cú pháp này có thể trong ví dụ cuối cùng của sed, ai đó có thể cho tôi biết tên của loại cú pháp này để tôi có thể tìm kiếm thêm về nó? - Kira
@Kira: The 1 có nghĩa là thực hiện lệnh tiếp theo chỉ trên một dòng của tệp và i lệnh được chèn. Tìm trong trang hướng dẫn người đàn ông trong phần "Địa chỉ" và trong phần "Lệnh không hoặc một địa chỉ". - Dennis Williamson
@ Terrance: Nếu sed lệnh trông giống như thế này (chèn một tab hàng đầu): '1i\tSome Text', bạn có thể cần phải tăng gấp đôi dấu gạch chéo ngược. Nếu không, phương ngữ của bạn sed có thể không nhận ra \t dưới dạng tab. - Dennis Williamson


Một lựa chọn đơn giản hơn trong quan điểm 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ủa $(...) đượ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à mèo mỗi ngày.

CHỈNH SỬA: 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 trong todo.txt, bởi vì nhờ -e cờ echo sẽ giải thích chúng. Một cách khác dễ dàng hơn để có được dòng mới vào chuỗi lời nói đầu là ...

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

... chỉ cần sử dụng dòng mới. Chắc chắn, nó không phải là một lớp lót nữa, nhưng thực tế nó không phải là một lớp lót trước đó. Nếu bạn đang làm điều này bên 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 hàm), có một số cách giải quyết để làm cho điều này vẫn hợp lý, 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 liệu một dòng mới có được thêm vào cuối todo.txt, đừng dùng cái này. Vâng, ngoại trừ cái thứ hai. Điều đó không gây rối với sự kết thúc.


60
2017-12-19 18:57



Tôi không nhận được $ (...) thực hiện ở tất cả. - SCL
Điều đó có thể làm việc tốt hơn (hoặc ở tất cả) với dấu ngoặc kép thay vì duy nhất… - ℝaphink
Sẽ không -e cũng chuyển đổi chuỗi thoát bên trong todo.txt? - mk12
Workarounds yield -> cat: <destination filename>: tập tin đầu vào là tập tin đầu ra ... - ingyhere
printf sẽ phù hợp hơn trên nhiều nền tảng và thường hoạt động trơn tru hơn echo -e - Peter Berg


Các moreutils có một công cụ tốt đẹp 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 tin, có nghĩa là bạn không phải lo lắng về các tập tin tạm thời và di chuyển chúng xung quanh.

Bạn có thể làm được moreutils với nhiều bản phân phối Linux, thông qua apt-get install moreutilshoặc trên OS X sử dụng Homebrew, với brew install moreutils.


26
2018-04-22 12:47





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

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

  2. i chèn

  3. x lưu và đóng


5
2018-04-11 00:23





Bạn có thể tạo một tệp tạm thời mớ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 sed hoặc là awk. Nhưng về cơ bản điều tương tự cũng xảy ra.


4
2018-02-17 03:26



Giả sử bạn đã hết dung lượng đĩa để new_todo.txt chỉ được viết một phần. Giải pháp của bạn dường như mất tệp gốc. - NPE
Ai hết dung lượng đĩa? ;-) Nó chỉ là một ví dụ đơn giản. - Keith
@Keith Ai đó đang 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 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 truy cập thư mục; nếu bạn không có quyền tạo tệp mới trong thư mục đã cho, lệnh duy nhất sẽ thực thi thành công trong tập lệnh của bạn là rm của tệp gốc. - Parthian Shot


Nếu tệp văn bản đủ nhỏ để vừa với bộ nhớ, bạn không phải tạo tệp tạm thời để thay thế tệp đó. Bạn có thể tải tất cả vào bộ nhớ và ghi nó ra 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 đè toàn bộ tệp.


3
2018-01-09 22:49



Chỉ cần hỏi câu hỏi hiển nhiên: Đâu là giới hạn ký tự của các biến hệ vỏ? - nixda
Theo như tôi biết, nó chỉ bị giới hạn bởi lượng bộ nhớ có sẵn. Tôi đã điền đầy đủ các biến hơn 100MB vào bộ nhớ. text=$(cat file). Hãy cẩn thận để chỉ sử dụng văn bản mặc dù, bởi vì các biến shell không phải là nhị phân sạch mywiki.wooledge.org/BashFAQ/058 - Rucent88


Bạn không thể chèn nội dung vào đầ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 hiện tại.

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

Cẩn thận với việc không làm mất dữ liệu bằng cách giữ nguyê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 suốt quá trình. ví dụ:

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

2
2018-02-17 06:25



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, làm mâu thuẫn với bất cứ điều gì trong câu trả lời của tôi. - jlliagre
Rất khó để phân tích cú pháp vì <...> trông giống như các dấu ngoặc đơn mà tôi cho là không. Một khoảng trống 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' làm việc nhưng cat <echo HOME=\"/g/Users/timregan/\" 'F:\Program Files\Git\etc\profile' cho lỗi "echo: Không có tập tin hoặc thư mục" - dumbledad
@dumbledad Bạn đang overthinking trả lời của tôi. Không có gì để bạn phân tích trong đó. Một khoảng cách giữa < và ( sẽ phá vỡ cú pháp. Thử cat <(echo HOME=\"/g/Users/timregan/\") 'F:\Program Files\Git\etc\profile' - jlliagre


Bạn có thể dùng tee:

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

0
2017-07-08 14:16



Không, bạn không thể askubuntu.com/a/752451 - Steven Penny


GitBash + Windows10 + Multline:

Đâ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]

0
2017-08-04 07:04





Mở rộng Subshell Bash

LINE="FOO"
echo -e "$LINE\n$(cat file)" > file

Điều này làm việc vì mở rộng subshell cat file mở một luồng IO tới tệp đã tồn tại trước khi nó bị ghi đè.

Ví dụ / Demo

echo "BAR" > file;
LINE="FOO"
echo -e "$LINE\n$(cat file)" > file

$ cat file 
FOO
BAR

0
2017-08-27 06:51