Làm cách nào để thêm văn bản vào đầu và cuối của nhiều tệp văn bản trong Bash?


24

Tôi có một thư mục đầy đủ các tập tin văn bản. Mục tiêu của tôi là nối thêm văn bản vào đầu và cuối của tất cả chúng. Văn bản đi ở đầu và cuối giống nhau cho mỗi tệp.

Dựa trên mã tôi nhận được từ web, đây là mã để nối vào đầu tệp:

echo -e 'var language = {\n$(cat $BASEDIR/Translations/Javascript/*.txt)' > $BASEDIR/Translations/Javascript/*.txt

Đây là mã để nối vào cuối tập tin. Mục tiêu là thêm văn bản };ở cuối mỗi tệp:

echo "};" >> $BASEDIR/Translations/Javascript/*.txt

Các ví dụ tôi rút ra là để hành động trên các tệp riêng lẻ. Tôi nghĩ tôi sẽ thử hành động trên nhiều tệp bằng cách sử dụng ký tự đại diện *.txt.

Tôi có thể đang phạm sai lầm khác là tốt. Trong mọi trường hợp, làm cách nào để thêm văn bản vào đầu và cuối của nhiều tệp?

Câu trả lời:


27

Để thêm văn bản vào một tệp bạn có thể sử dụng (với triển khai GNU sed):

sed -i '1i some string' file

Nối văn bản đơn giản như

echo 'Some other string' >> file

Điều cuối cùng cần làm là đặt nó vào một vòng lặp lặp lại trên tất cả các tệp bạn định chỉnh sửa:

for file in *.txt; do
  sed -i '1i Some string' "$file" &&
  echo 'Some other string' >> "$file"
done

8

Bạn có thể sử dụng GNU sed

Giống như đã được minh họa, bạn có thể chèn các dòng văn bản ngay trước và sau khi khớp các dòng của tệp với sed, sử dụng lệnh ialệnh tương ứng. Những gì chưa được hiển thị là bạn có thể làm điều đó với một lớp lót và cho nhiều tệp cùng một lúc.

Sau đây sẽ chèn một dòng trước dòng đầu tiên 1ivà sau dòng cuối cùng $a. Các phần chèn thêm sẽ được thực thi cho tất cả các tệp khớp với toàn cục *.txt.

sed -i -e '1ivar language = {' -e '$a};' -- *.txt

Cả hai iakhông chỉ hoạt động với số dòng, mà còn trên mỗi dòng phù hợp với một mẫu nhất định. Điều này sẽ chèn một bình luận bất cứ khi nào một dòng chứa var y = 2;:

sed -i -- '/var y = 2;/i//initialize variable y' *.js

5

Lệnh tuân thủ hoàn toàn POSIX, sử dụng ex:

for f in *.txt; do printf '%s\n' 0a 'var language = {' . '$a' '};' . x | ex "$f"; done

Nếu bạn tự chạy printfphần lệnh, bạn sẽ thấy các lệnh chỉnh sửa chính xác mà nó đang truyền tới ex:

0a
var language = {
.
$a
};
.
x

0acó nghĩa là "Nối văn bản sau dòng 0" (nói cách khác, trước dòng đầu tiên). Dòng tiếp theo là văn bản bằng chữ "nối thêm" sau dòng 0. Dấu .chấm ( ) trên một dòng tự kết thúc văn bản sẽ được nối thêm.

$a có nghĩa là nối thêm văn bản sau dòng cuối cùng của tệp.

x có nghĩa là lưu các thay đổi và thoát.


2

Đây là một cách để làm điều đó trong Perl:

for f in ./*txt; do
  perl -lpe 'BEGIN{print "First string"}END{print "Last string"}' "$f" > foo && 
  mv foo "$f";
done

@ StéphaneChazelas thêm -ithay vì tập tin thay thế này không hoạt động, nó chỉ in ra thiết bị xuất chuẩn.
Oleh Prypin

@OlehPrypin, thực sự là quyền của bạn. Bình luận đã bị xóa.
Stéphane Chazelas

1

Hãy thử sử dụng ex:

ex -s +'bufdo!1s/^/HEAD/|$s/$/TAIL/' -cxa *.foo

trong đó các lệnh là:

  • bufdo!thực thi các lệnh bên dưới cho mỗi bộ đệm / tệp đã mở (lưu ý: đó không phải là POSIX )
  • 1s/^/HEAD/- chèn HEADvăn bản vào dòng đầu tiên ở đầu dòng
  • $s/$/TAIL/- nối TAILvăn bản trên dòng cuối cùng ở cuối dòng

và các đối số là:

  • -s - chế độ im lặng / nhanh
  • -cxa - lưu tất cả các bộ đệm / tập tin đã mở và thoát
  • *.foo- tất cả các file trong thư mục hiện ( *) với foophần mở rộng, sử dụng **/*.foocho đệ quy (sau khi kích hoạt globstar: shopt -s globstar)


1
@StevenPenny nói đúng. Cá nhân tôi chỉ sử dụng các tính năng được chỉ định POSIX cho các chỉnh sửa theo kịch bản.
tự đại diện

1

Với gnu awk, sử dụng inplacetiện ích mở rộng và BEGINFILE/ ENDFILE:

gawk -i inplace 'BEGINFILE{print "INSERT"};ENDFILE{print "APPEND"};1' ./*.txt

1

Cũng có quyền được (có kết quả trong .outtệp):

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.out' \;

Một biến thể khác, công phu hơn - các tệp nguồn được thay thế bằng kết quả:

find . -name '*.txt' -exec sh -c '(echo HEAD;cat {};echo FOOT) > {}.tmp && mv {}.tmp {}' \; -print

0

Perl one-liner để giải cứu:

perl -i -pe'$_="FIRST LINE\n$_"if$.<2;$.=0,$_.="LAST LINE\n"if eof' *.txt
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.