Làm thế nào để chèn văn bản trước dòng đầu tiên của một tập tin?


76

Tôi đã tìm kiếm sedlệnh để thêm văn bản vào một tệp trong một dòng cụ thể. Công việc này thêm văn bản sau dòng 1:

sed '1 a\

Nhưng tôi muốn thêm nó trước dòng 1. Nó sẽ là:

sed '0 a\

nhưng tôi nhận được lỗi này : invalid usage of line address 0.

Bất cứ đề nghị nào?


Câu trả lời:


101

Sử dụng tùy chọn sedinsert ( i) sẽ chèn văn bản vào dòng trước.

sed '1 i\

Cập nhật câu hỏi của tác giả:

Để làm cho nó chỉnh sửa tệp tại chỗ - với GNU sed- tôi đã phải thêm -itùy chọn:

sed -i '1 i\anything' file

Ngoài ra cú pháp

sed  -i '1i text' filename

Đối với sed không GNU

Bạn cần nhấn phím quay lại ngay sau dấu gạch chéo ngược 1i\và sau first_line_text:

sed -i '1i\
first_line_text
'

Cũng lưu ý rằng một số sedtriển khai không phải GNU (ví dụ như triển khai trên macOS) yêu cầu một đối số cho -icờ (sử dụng -i ''để có được hiệu ứng tương tự như với GNU sed).


1
Nó không hoạt động mà không có -itùy chọn. Tôi sẽ cập nhật câu trả lời của bạn trước khi chấp nhận.
Manolo

1
cảm ơn. Bạn đang sử dụng hệ điều hành nào? Giải pháp ban đầu làm việc trên OpenSuse 9.
suspectus

1
Hấp dẫn! Tôi đang dùng LubFi 13.10 và sed '1 i\this text is entered above the existing first line' filelàm việc cho tôi.

2
Ở đây, sử dụng sed (GNU sed) 4.2.2chỉ sed '1 i text to insert' -i filelàm việc như một nét duyên dáng. Cảm ơn
tấn

1
@FeRD Xem awkcâu trả lời xếp hạng xấu của tôi dưới đây. Điều này nên làm việc.
rudimeier

18

Echo được sử dụng để có được văn bản. Tên tệp con mèo - in tệp trong bàn điều khiển và> sử dụng nó để gửi đến một tệp khác tên tệp1 và sau đó chúng tôi di chuyển tên tệp1 sang tên tệp để đưa văn bản vào dòng đầu tiên của tệp mong muốn.

  (echo "some text" && cat filename) > filename1 && mv filename1 filename

7
Xin vui lòng cho tôi biết lý do tại sao những điều sau đây bị hạ cấp
Ankit Shah

1
Có lẽ vì OP đề cập đến sed. Điều đó không xứng đáng với một cuộc bỏ phiếu theo ý kiến ​​của tôi. Giải pháp đó thậm chí phù hợp nhất với nhu cầu của tôi, sau đó được nâng cấp.
hôm nay

Tôi ủng hộ. làm việc trên ksh cho tôi.
arcee123

16

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

ex -sc '1i|ALFA BRAVO' -cx file
  1. 1 chọn dòng đầu tiên

  2. i chèn văn bản và dòng mới

  3. x lưu và đóng


7

Bạn muốn chèn văn bản trước dòng đầu tiên thay vì nối thêm nó sau, vì vậy hãy sử dụng

sed '1 i\
your_text' your_file

Một tài liệu ở đây cũng có thể giúp:

cat /dev/stdin your_file <<EOI
Your text
goes here
EOI

6

Sử dụng GNU awk> = 4.1:

awk -i inplace 'BEGINFILE{print "first line"}{print}' foo.sh

Ngược lại với tất cả các sedcâu trả lời, điều này cũng hoạt động trên các tệp trống.


inplacelà một thư viện, và không may nó xuất hiện trên tất cả các bản phân phối awk gửi nó. Tôi nhận được "awk: fatal: không thể mở tệp nguồn 'inplace' để đọc"GNU Awk 4.2.1, API: 2.0 (GNU MPFR 4.0.1, GNU MP 6.1.2)
vossad01

6
sed  -i '1i new_text' file_name

Nếu bạn không chỉ định -itùy chọn, nó sẽ không hiển thị bất kỳ lỗi nào và hiển thị đầu ra trên thiết bị đầu cuối tiêu chuẩn, nhưng không chèn văn bản vào tệp.


Câu hỏi không phải là về việc -ichuyển đổi.
don_crissti 14/03/2016

Làm thế nào để bạn tìm thấy? Đó một câu trả lời cho câu hỏi. Vâng, nó tương tự như câu trả lời được chấp nhận, nhưng không hoàn toàn giống nhau.
G-Man

@ G-Man - người ta có thể lập luận rằng mẫu được sử dụng bởi cas rất xa lý tưởng nhưng thực sự, nó giống như gần giống nhau ... sự khác biệt là khoảng cách và thực tế mẫu này không có dấu gạch chéo ngược. Theo như tôi quan tâm thì chúng giống hệt nhau về mặt kỹ thuật (vì cả hai đều gnu sedcụ thể và nó chỉ xảy ra gnu sedsẽ chấp nhận imà không có dấu gạch chéo ngược). Nếu những người khác nghĩ rằng điều này đảm bảo một câu trả lời riêng + một upvote ... oh tốt.
don_crissti

2

Các 0alệnh mà bạn đã cố gắng không làm việc trong ex, tiền thânvi :

printf '%s\n' 0a 'Anything you want to add' . x | ex file.txt

Các printflệnh bằng cách tự kết quả đầu ra:

0a
Anything you want to add
.
x

0anghĩa là nối sau dòng 0 (tức là trước dòng đầu tiên).

Dòng tiếp theo hoặc nhiều dòng là văn bản bằng chữ được thêm vào.

Trên .một dòng tự chấm dứt lệnh "chắp thêm".

Các xnguyên nhân Ex để lưu các thay đổi vào tệp và thoát.


1

Tôi ngạc nhiên rằng trong câu hỏi cũ này, không ai chỉ ra lệnh sed phổ biến nhất (và khá đơn giản trong trường hợp này):

$ sed  -i '1s/^/new_text\
/' file_name

Mà hoạt động trong hầu hết các shell và có thể di chuyển đến một số phiên bản sed.
Nếu GNU sed có sẵn, bạn có thể sử dụng điều này:

$ sed -i '1s/^/new_text\n' file_name

Sự khác biệt là GNU sed cho phép sử dụng \nmột dòng mới và những cái khác cần một dòng mới theo nghĩa đen trước dấu gạch chéo ngược (dù sao nó cũng hoạt động trong GNU sed).

Nếu hệ vỏ chấp nhận $'…'cú pháp đang được sử dụng, bạn có thể chèn dòng mới trực tiếp, vì vậy sed thấy rằng dòng mới đã có:

$ sed -i $'1s/^/new_text\\\n/' file_name

Mà hoạt động cho các phiên bản sed nhiều hơn.


-1

Thật không may, tất cả các câu trả lời ở trên (chủ yếu là với sed) không phù hợp với tôi vì tất cả chúng đều thay thế dòng đầu tiên. Tôi đang trên một Ubuntu 16.04 LTScái máy. Đây là cách giải quyết của tôi với GNU Awk 4.0.2:

awk '{if(NR==1){$0="NEW_FIRST_LINE"$0; print $0} ;if(NR!=1){print $0}}' file_name

1
Không chắc chắn những gì bạn đang nói về ... Chỉ có một sedcâu trả lời sử dụng thay thế nhưng nó không thay thế dòng hiện có.
don_crissti

-1

Đầu tiên và cuối cùng

Tôi cho rằng bất cứ ai tìm kiếm cách chèn / nối văn bản vào đầu / cuối của một tập tin cũng có thể cần phải biết cách làm khác.

cal |                            \
  gsed -E                        \
       -e     '1i\{'             \
       -e     '1i\  "lines": ['  \
       -e 's/(.*)/    "\1",/'    \
       -e '$s/,$//'              \
       -e     '$a\  ]'           \
       -e     '$a\}'

Giải trình

Đây là calđầu ra được dẫn đến gnu- sed(được gọi gsedtrên macOS được cài đặt qua brew.sh ) với RegEx ( -E) và 6 "script" được áp dụng ( -e) và ngắt dòng được thoát ra \để dễ đọc. Tập lệnh 1 & 2 sử dụng 1i\để "ở dòng 1, chèn". Tập lệnh 5 & 6 sử dụng $a\để "tại dòng <cuối>, nối thêm". Tôi căn chỉnh theo chiều dọc các đầu ra văn bản để làm cho mã đại diện cho những gì được mong đợi trong kết quả. Tập lệnh 3 & 4 thực hiện thay thế (đoạn sau chỉ áp dụng cho "dòng <cuối>"). Kết quả là chuyển đổi đầu ra lệnh thành JSON hợp lệ.

đầu ra

{
  "lines": [
    "    October 2019      ",
    "Su Mo Tu We Th Fr Sa  ",
    "       1  2  3  4  5  ",
    " 6  7  8  9 10 11 12  ",
    "13 14 15 16 17 18 19  ",
    "20 21 22 23 24 25 26  ",
    "27 28 29 30 31        ",
    "                      "
  ]
}

Mặc dù tôi đã bỏ phiếu cho câu hỏi của bạn, lưu ý rằng chúng tôi đã có một số câu trả lời, bao gồm câu trả lời được chấp nhận, thể hiện kết quả mong muốn.
Jeff Schaller

@JeffSchaller Cộng đồng Stack Exchange không phải là một diễn đàn. Mục đích của nó mở rộng ra ngoài việc giúp OP không bị chặn. Mục tiêu là gieo mầm nền tảng kiến ​​thức toàn cầu với nhiều lựa chọn mà người tìm kiếm có thể vấp ngã khi tìm kiếm câu trả lời. Lý do tôi đặt tiêu đề cho câu trả lời của mình là để giúp người dùng nhận ra tiện ích của câu trả lời này trước khi họ nhấp vào kết quả của Google.
Bruno Bronosky

Điều tôi đang nói là câu trả lời của bạn không cung cấp bất kỳ tùy chọn mới (câu trả lời) nào cho người đọc tương lai của câu hỏi này. Chúng tôi đã có bốn câu trả lời sử dụng các biến thể của 1iđể chèn văn bản trước dòng đầu tiên. Một người có câu hỏi này sẽ phải trích xuất những phần họ cần từ câu trả lời của bạn để giải quyết vấn đề của họ. Câu hỏi là miễn phí, vì vậy tôi mời bạn hỏi và trả lời câu hỏi của riêng bạn để cung cấp câu trả lời cụ thể của bạn.
Jeff Schaller
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.