Câu trả lời:
Đầu tiên, lưu dữ liệu được mã hóa base64 trong một tệp có tên, ví dụ : base64.txt.
Ví dụ:
base64 < originalfile > base64.txt
Sau đó:
printf '%s\n' '/BASE64/r base64.txt' 1 '/BASE64/d' w | ed FILENAME
Điều này sử dụng edđể tìm kiếm FILENAMEmột dòng chứa chuỗi BASE64, chèn nội dung của base64.txtsau dòng đó, quay lại dòng đầu tiên, sau đó tìm kiếm lại dòng có chuỗi BASE64và xóa nó. Các wchỉ huy edlưu các tập tin sửa đổi.
/BASE64/r base64.txtchèn như trên, và sau đó s/BASE64//hơn là /BASE64/d.
s/BASE_64/$BASE_64_TEXT/với sed hoặc ed hoặc perl hoặc bất cứ điều gì có thể sẽ đủ.
Bạn luôn có thể làm (vì bạn đã sử dụng GNU sedrồi ( -i)):
sed -i -f - FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF
-f -nói sedđể đọc kịch bản sed từ stdin.
Nếu bạn muốn sử dụng lại kịch bản tương tự cho một số tập tin, trên Linux (và chỉ Linux), với một vỏ như bash, zsh, kshmà cụ ở đây các tài liệu với các tập tin tạm thời (như trái ngược với ống như dashhoặc yash) và vẫn với GNU sed, bạn có thể làm:
find . -name '*.conf' -exec sed -i -f /dev/stdin {} + << EOF
s/BASE_64/$BASE_64/g
EOF
Trên Linux (và chỉ Linux), /dev/stdinkhông có nghĩa là stdin theo cùng một cách -. Thay vào đó, nó là một liên kết tượng trưng đến tệp được mở trên stdin, vì vậy mỗi lần sedmở tệp, nó sẽ mở tệp lại từ đầu. Lệnh trên sẽ hoạt động tốt trên các hệ thống khác (có /dev/stdin) hoặc với hệ vỏ thực hiện ở đây - tài liệu có đường ống nhưng chỉ khi có ít conftệp đủ sedđược gọi một lần. Khi được gọi lần thứ hai, trên các hệ thống không phải Linux, như với -f -, /dev/stdinsẽ xuất hiện trống rỗng vì nó đã được đọc bởi lệnh gọi đầu tiên.
busybox sedcũng hỗ trợ -itheo cách tương tự như GNU sed, nhưng không hỗ trợ -f -. Vì vậy, bạn muốn sử dụng -f /dev/stdinở đó trong mọi trường hợp. Với FreeBSD sed, sử dụng:
sed -i '' -f /dev/stdin FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF
Một lựa chọn khác sẽ được thay thế sedvới edvà lưu trữ các lệnh của bạn trong một tập tin. Ví dụ: nếu bạn tạo ed_cmdsvới các nội dung sau:
%s/BASE_64/<expanded variable>/g
w
q
sau đó bạn có thể chạy
< ed_cmds ed FILE_NAME
và nó sẽ thực hiện các thay đổi bạn muốn, vì vậy thay vì cài đặt, $BASE_64bạn sẽ tạo tệp lệnh ed.
Ed Giải thích
% có nghĩa là áp dụng lệnh cho từng dòng của tệps/pat1/pat2/gsự thay thế xuất hiện của pat1với pat2và gcuối cùng làm cho nó làm điều đó cho mọi trận đấu trên đường, không chỉ lần đầu tiênw ghi các thay đổi vào đĩaq thoát (điều này sẽ xảy ra khi nó có EOF)Tất nhiên, bạn cũng có thể đặt các sedlệnh của mình vào một tệp và sử dụng -f, nhưng nếu bạn đang làm điều đó và bạn muốn sửa đổi tệp tại chỗ, bạn cũng có thể sử dụng edthay vì tạo một tệp tạm thời và di chuyển nó như sed -ivậy.
Kích thước của biểu diễn Base64 của tệp ($ BASE_64) quá dài và vượt quá kích thước đối số tối đa. Bạn sẽ có thể thấy giới hạn này cho hệ thống của mình bằng cách chạy
getconf ARG_MAX
Bạn phải tăng kích thước của ARG_MAXgiá trị. Nhưng tôi nghĩ nếu tập tin quá lớn, thì bạn sẽ phải sử dụng một cách tiếp cận khác để thực hiện việc thay thế này. Nếu một kịch bản Python sẽ làm điều đó cho bạn, tôi cũng sẽ thử nó với nó.
ARG_MAXkhông thực hiện thậm chí giúp đỡ đó.
Tôi đã kết thúc việc đưa các sedhướng dẫn vào một tập tin
SEDCOMMANDS=`tempfile`
và được gọi
sed -f "$SEDCOMMANDS" -- "$FILE_NAME"
Điều đó tốt nếu bạn không sử dụng sed -i. Nếu bạn muốn chỉnh sửa tệp tại chỗ, hãy làm theo https://unix.stackexchange.com/a/284188/149867 và đặt các edhướng dẫn tương đương trong một tệp, theo sau wvà q.
-ihoạt động tốt với -f. Chỉ, đảm bảo bạn sử dụng -i -f(hoặc -i '' -fvới BSD sed), không -if. Bạn cũng có thể sử dụng-f - để tránh các tập tin tạm thời.
BASE64chỉ là một phần của dòng và bạn không muốn thay thế toàn bộ dòng?