Cách nối nhiều dòng vào một tệp


301

Tôi đang viết một tập lệnh bash để tìm tập tin nếu nó không tồn tại, sau đó tạo nó và nối nó vào tập tin đó:

Host localhost
    ForwardAgent yes

Vì vậy, "line then new line 'tab' then text"tôi nghĩ rằng nó là một định dạng nhạy cảm. Tôi biết bạn có thể làm điều này:

cat temp.txt >> data.txt

Nhưng nó có vẻ kỳ lạ kể từ hai dòng của nó. Có cách nào để nối thêm vào định dạng này không:

echo "hello" >> greetings.txt

Câu trả lời:


526
# possibility 1:
echo "line 1" >> greetings.txt
echo "line 2" >> greetings.txt

# possibility 2:
echo "line 1
line 2" >> greetings.txt

# possibility 3:
cat <<EOT >> greetings.txt
line 1
line 2
EOT

Nếu sudo (đặc quyền người dùng khác) là cần thiết để ghi vào tệp, sử dụng:

# possibility 1:
echo "line 1" | sudo tee -a greetings.txt > /dev/null

# possibility 3:
sudo tee -a greetings.txt > /dev/null <<EOT
line 1
line 2
EOT

2
@TheLegend Đó được gọi là "tài liệu ở đây". Có một cái nhìn vào đoạn đó trong trang người đàn ông.
Hauke ​​Laging

1
Một khả năng nữa là ( echo "line 1" ; echo "line 2" ) >>greetings.txt.
ott--

2
@ ott-- Bạn không cần một mạng con thực sự (nghĩa là có thể lưu một quy trình mới), thế là đủ:{ echo "line 1" ; echo "line 2"; } >>greetings.txt
Hauke ​​Laging

2
sự khác biệt giữa EOT và EOL là gì?
cikatomo

15
@cikatomo Trong cat <<EOTnhững EOTchỉ là một chuỗi ngẫu nhiên. Có thể là cat <<FOOquá.
Hauke ​​Laging

60
printf '%s\n    %s\n' 'Host localhost' 'ForwardAgent yes' >> file.txt

Hoặc, nếu đó là một tab theo nghĩa đen mà bạn muốn (chứ không phải là bốn khoảng trắng trong câu hỏi của bạn):

printf '%s\n\t%s\n' 'Host localhost' 'ForwardAgent yes' >> file.txt

Bạn có thể đạt được hiệu quả tương tự với echo, nhưng chính xác cách thay đổi từ thực hiện đến thực hiện, trong khi đó printflà không đổi.



16

Một cách tiếp cận khác là sử dụng tee

tee -a ~/.ssh/config << END
Host localhost
  ForwardAgent yes
END

Một vài dòng lựa chọn từ teetrang man của:

Tiện ích tee sao chép đầu vào tiêu chuẩn thành đầu ra tiêu chuẩn, tạo một bản sao trong không hoặc nhiều tệp.

-a - Nối đầu ra vào các tệp thay vì ghi đè lên chúng.


6

SED có thể nối một dòng vào cuối tệp như vậy:

sed -i '$ a text to be inserted' fileName.file
$chọn kết thúc tệp, thông báo ađể nối thêm và sau đó xuất hiện văn bản sẽ được chèn. Sau đó, tất nhiên tên tập tin.


Nguồn: http://www.yourownlinux.com/2015/04/sed-command-in-linux-append-and-insert-lines-to-file.html

========== EDIT == ==========

Cách tiếp cận này có bất kỳ lợi ích bổ sung nào hơn các giải pháp khác không?
Có, cách tiếp cận này có thêm lợi ích của việc thêm vào bất kỳ tệp nào trả về trong một tìm kiếm, chẳng hạn như: find . -name "*.html" -exec sed -i '$ a </html>' {} \;

Tôi đã sử dụng ví dụ trên để chèn thẻ html kết thúc bị thiếu trên mỗi trang html trong một số thư mục.

===================================


1
Nếu bạn sẽ hiển thị cú pháp nối thêm nhiều dòng vào một tệp, thì đây sẽ là một câu trả lời cho câu hỏi (mặc dù không phải là một câu rất hữu ích). Tất cả các câu trả lời khác chỉ đơn giản là viết văn bản mới. Câu trả lời này đọc toàn bộ tập tin và viết lại, cộng với văn bản được thêm vào. Liệu phương pháp này có bất kỳ lợi ích hơn những người khác?
G-Man

Điều này chỉ hoạt động với GNU sed. BSD bảo lãnh sedvới lỗi : command a expects \ followed by text. Vì vậy, không sử dụng điều này cho một giải pháp kịch bản; nó có thể bị phá vỡ. (Hoặc thực hiện đúng vì cú pháp yêu cầu BSD tương thích POSIX và cũng sẽ hoạt động trên GNU sed.
Wildcard

Các câu trả lời khác có thể được sử dụng findnhư sau : find . -name "*.txt" -exec sh -c 'printf "%s\n\t%s\n" "Host localhost" "ForwardAgent yes" >> "$1"' sh {} ";".
G-Man

1
Đây là một giải pháp rất tốt, vì nó không thực hiện chuyển hướng luồng ( >, >>) và do đó không gặp phải các vấn đề như chạy sudo echo 'something' > /file. Đối với tôi, nó hoàn toàn cho phép nối một dòng vào một tệp trong thùng chứa lxd như thế : lxc exec c sed -- '$ a newline' /myfile.
Draco Ater

Các echo "a new line" >> foo.filesẽ không tạo ra một dòng mới khi tập tin được không kết thúc của dòng sản phẩm mới, nhưng sed -i '$ a a new line' foo.filesẽ làm, vì vậy sedlà tốt hơn đặc biệt là bạn muốn luôn nối thêm một dòng mới vào tập tin.
zhouji

1

Tôi đã sử dụng sed vì nó có thể được sử dụng với sudo. Ví dụ:

sudo sed -i '$ a text to be inserted' fileName.file 

sự thay thế rất xấu xí như:

sudo bash -c "echo a text to be inserted >> fileName.file"  

và thậm chí xấu hơn khi thực hiện với ssh.


1
Tại sao câu trả lời này bị hạ thấp? Đây trông giống như giải pháp tôi cần. Có vấn đề gì với nó không? Nếu không, tôi sẽ sử dụng nó và nâng cấp nó.
MountainX

Bạn sed -ikhông lấy một phần mở rộng làm đối số? Ví dụ của bạn có thể có các tham số không chính xác.
protometa

1

Một lớp lót khác là:

echo "Greetings 1" >> greetings.txt && echo "Greetings 2" >> greetings.txt

Tôi thích -etùy chọn này, vì nó mang lại nhiều quyền kiểm soát hơn:

echo -e "Greeting 1\nGreetings 2\n" >> greetings.txt

1

Người ta có thể mô phỏng cat >> out.txtvới Perl hoặc Python để đạt được hiệu quả tương tự. Perl:

perl -e 'open(fh,">>","./out.txt");while(<>){printf(fh "%s",$_)};close(fh);'

Và Python:

python -c 'import sys;f=open(sys.argv[1],"a");l=[i for i in sys.stdin];f.write("".join(l))' out.txt 

Lưu ý rằng đối với trăn bạn sẽ phải đánh Ctrl+ Dhai lần. Xem câu hỏi liên quan trên stackoverflow để biết thêm.


1

Dưới đây là một ví dụ để nối thêm nhiều dòng trong một tệp:

{
        echo '  directory "/var/cache/bind";'
        echo '  listen-on { 127.0.0.1; };'
        echo '  listen-on-v6 { none; };'
        echo '  version "";'
        echo '  auth-nxdomain no;'
        echo '  forward only;'  
        echo '  forwarders { 8.8.8.8; 8.8.4.4; };'
        echo '  dnssec-enable no;'
        echo '  dnssec-validation no;'
} >> your_file.txt

0

Ngoài câu trả lời chính, trong trường hợp tệp cần có quyền siêu người dùng, chỉ cần thêm sudovào trước echosẽ không hoạt động.

Điều này là do shell phá vỡ các lệnh và mặc dù echođã chạy bằng root, nhưng >>chạy với các đặc quyền bình thường.

Điều này sẽ làm việc cho siêu người dùng: sudo su -c "echo 'Line 3' >> greetings.txt"


Bạn không cần suở đây ( sudo sukhông tốt). Nhưng bạn đúng ở chỗ bạn cần một cái gì đó để quản lý chuyển hướng vỏ; có lẽ sudo sh -c "echo stuff >> file.txt". Không tiết kiệm ròng nhưng thực hành tốt hơn.
roaima
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.