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 FILENAME
một dòng chứa chuỗi BASE64
, chèn nội dung của base64.txt
sau dòng đó, quay lại dòng đầu tiên, sau đó tìm kiếm lại dòng có chuỗi BASE64
và xóa nó. Các w
chỉ huy ed
lưu các tập tin sửa đổi.
/BASE64/r base64.txt
chè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 sed
rồ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
, ksh
mà 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ư dash
hoặ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/stdin
khô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 sed
mở 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 conf
tệ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/stdin
sẽ xuất hiện trống rỗng vì nó đã được đọc bởi lệnh gọi đầu tiên.
busybox
sed
cũng hỗ trợ -i
theo 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ế sed
với ed
và 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_cmds
vớ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_64
bạ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/g
sự thay thế xuất hiện của pat1
với pat2
và g
cuố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 sed
lệ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 ed
thay vì tạo một tệp tạm thời và di chuyển nó như sed -i
vậ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_MAX
giá 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_MAX
không thực hiện thậm chí giúp đỡ đó.
Tôi đã kết thúc việc đưa các sed
hướ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 ed
hướng dẫn tương đương trong một tệp, theo sau w
và q
.
-i
hoạt động tốt với -f
. Chỉ, đảm bảo bạn sử dụng -i -f
(hoặc -i '' -f
vớ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.
BASE64
chỉ là một phần của dòng và bạn không muốn thay thế toàn bộ dòng?