Tôi đang sử dụng mã bên dưới để thay thế một chuỗi bên trong một tập lệnh shell.
echo $LINE | sed -e 's/12345678/"$replace"/g'
nhưng nó được thay thế bằng $replace
thay vì giá trị của biến đó.
Ai có thể cho biết điều gì đã xảy ra?
Tôi đang sử dụng mã bên dưới để thay thế một chuỗi bên trong một tập lệnh shell.
echo $LINE | sed -e 's/12345678/"$replace"/g'
nhưng nó được thay thế bằng $replace
thay vì giá trị của biến đó.
Ai có thể cho biết điều gì đã xảy ra?
Câu trả lời:
Nếu bạn muốn diễn giải $replace
, bạn không nên sử dụng dấu ngoặc kép vì chúng ngăn cản việc thay thế biến.
Thử:
echo $LINE | sed -e "s/12345678/\"${replace}\"/g"
giả sử bạn muốn đặt dấu ngoặc kép. Nếu bạn không muốn dấu ngoặc kép, hãy sử dụng:
echo $LINE | sed -e "s/12345678/${replace}/g"
Bảng điểm:
pax> export replace=987654321
pax> echo X123456789X | sed "s/123456789/${replace}/"
X987654321X
pax> _
Chỉ cần cẩn thận để đảm bảo rằng ${replace}
không có bất kỳ ký tự nào có ý nghĩa sed
(chẳng /
hạn như) vì nó sẽ gây nhầm lẫn trừ khi được thoát ra. Nhưng nếu, như bạn nói, bạn đang thay thế một số này bằng một số khác, thì đó không phải là vấn đề.
set
cũng không cần thiết (và bạn sẽ sử dụng nó như thế nào?). Chỉ là replace=987654321
.
export
để đảm bảo rằng các biến được đặt cho trẻ em nhưng, như bạn nói, bạn có thể dễ dàng tránh nó. Tuy nhiên, việc sử dụng hay không export
là không liên quan ở đây (vấn đề về kiểu dáng) và không ảnh hưởng đến câu trả lời thực tế, đó là cách sử dụng các biến trong một sed
lệnh.
-i
tùy chọn. Bạn có biết tại sao không? hoặc làm thế nào để làm cho nó hoạt động?
$
hoặc `
trong sed
tập lệnh phải được thoát bằng dấu gạch chéo ngược, để bảo vệ nó khỏi cơ chế thay thế của trình bao cho các chuỗi được trích dẫn kép.
bạn có thể sử dụng shell (bash / ksh).
$ var="12345678abc"
$ replace="test"
$ echo ${var//12345678/$replace}
testabc
/bin/sh
trên nhiều Linux hiện đại.
Không dành riêng cho câu hỏi, nhưng dành cho những người cần cùng loại chức năng được mở rộng để rõ ràng hơn từ các câu trả lời trước:
# create some variables
str="someFileName.foo"
find=".foo"
replace=".bar"
# notice the the str isn't prefixed with $
# this is just how this feature works :/
result=${str//$find/$replace}
echo $result
# result is: someFileName.bar
str="someFileName.sally"
find=".foo"
replace=".bar"
result=${str//$find/$replace}
echo $result
# result is: someFileName.sally because ".foo" was not found
Tìm thấy một giải pháp duyên dáng .
echo ${LINE//12345678/$replace}
echo $LINE | sed -e 's/12345678/'$replace'/g'
bạn vẫn có thể sử dụng các dấu ngoặc kép, nhưng bạn phải "mở" chúng khi bạn muốn biến được mở rộng đúng chỗ. nếu không thì chuỗi được coi là "theo nghĩa đen" (như @paxdiablo đã nói đúng, câu trả lời của anh ấy cũng đúng)
$replace
bên ngoài bất kỳ dấu ngoặc kép nào sẽ khiến trình bao thực hiện mã hóa khoảng trắng và mở rộng ký tự đại diện trên giá trị. Điều này có vẻ hoạt động với các giá trị đơn giản, nhưng có thể làm nổ tung đáng kể trên các chuỗi không đáng kể. Không sử dụng điều này trong mã sản xuất.
Để cho phép shell của bạn mở rộng biến, bạn cần sử dụng dấu ngoặc kép như
sed -i "s#12345678#$replace#g" file.txt
Điều này sẽ bị phá vỡ nếu $replace
chứa các sed
ký tự đặc biệt ( #
, \
). Nhưng bạn có thể xử lý trước $replace
để trích dẫn chúng:
replace_quoted=$(printf '%s' "$replace" | sed 's/[#\]/\\\0/g')
sed -i "s#12345678#$replace_quoted#g" file.txt
Tôi đã có một yêu cầu tương tự cho điều này nhưng var thay thế của tôi chứa một ký hiệu và. Thoát khỏi ký hiệu và như thế này đã giải quyết được vấn đề của tôi:
replace="salt & pepper"
echo "pass the salt" | sed "s/salt/${replace/&/\&}/g"
Sử dụng cái này thay thế
echo $LINE | sed -e 's/12345678/$replace/g'
điều này phù hợp với tôi chỉ đơn giản là xóa các dấu ngoặc kép
Tôi thích sử dụng dấu ngoặc kép hơn, vì các quptes đơn rất mạnh khi chúng ta sử dụng chúng nếu không thể thay đổi bất cứ thứ gì bên trong nó hoặc có thể gọi nhóm thay thế biến.
vì vậy hãy sử dụng dấu ngoặc kép được cài sẵn.
echo $LINE | sed -e "s/12345678/$replace/g"