2010-07-22 41 views
61

Tôi đang sử dụng mã bên dưới để thay thế chuỗi bên trong tập lệnh trình bao.Thay thế chuỗi trong tập lệnh shell bằng biến số

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?

+0

Đối với câu hỏi liên quan phổ biến về việc xử lý các giá trị có dấu gạch chéo trong chúng, hãy xem http://stackoverflow.com/questions/5864146/use-slashes-in-sed-replace – tripleee

Trả lời

87

Nếu bạn muốn giải thích $replace, bạn không nên sử dụng dấu nháy đơn vì chúng ngăn thay đổi biến.

Hãy thử:.

echo $LINE | sed -e "s/12345678/\"${replace}\"/g" 

giả sử bạn muốn có dấu ngoặc kép đưa vào Nếu bạn không muốn có dấu ngoặc kép, sử dụng:

echo $LINE | sed -e "s/12345678/${replace}/g" 

Transcript:

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ỳ charac ters của ý nghĩa để sed (ví dụ như /) vì nó sẽ gây nhầm lẫn trừ khi thoát. Nhưng nếu, như bạn nói, bạn đang thay thế một số với nhau, điều đó không phải là một vấn đề.

+0

tôi không muốn báo giá được đặt in.i muốn một số được thay thế bằng – Vijay

+2

'xuất' khác là không cần thiết. –

+1

paxdiablo: 'set' cũng không cần thiết (và bạn định sử dụng nó như thế nào?). Chỉ cần 'thay thế = 987654321'. –

3
echo $LINE | sed -e 's/12345678/'$replace'/g' 

bạn vẫn có thể sử dụng dấu nháy đơn, nhưng bạn phải "mở" chúng khi bạn muốn biến được mở rộng ở đúng vị trí. nếu không thì chuỗi được lấy "theo nghĩa đen" (như @paxdiablo đã được khai báo chính xác, câu trả lời của anh ấy cũng chính xác)

+0

Điều này có vấn đề là việc sử dụng '$ replace' bên ngoài bất kỳ dấu ngoặc kép nào sẽ làm cho trình bao thực hiện mã thông báo khoảng trắng và mở rộng ký tự đại diện trên giá trị. Điều này sẽ xuất hiện để làm việc với các giá trị đơn giản, nhưng có thể thổi lên đáng kể trên các chuỗi không đặc biệt. Không sử dụng mã này trong mã sản xuất. – tripleee

52

bạn có thể sử dụng trình bao (bash/ksh).

$ var="12345678abc" 
$ replace="test" 
$ echo ${var//12345678/$replace} 
testabc 
+3

Có thể muốn đề cập đến đó là bash cụ thể (và ksh?). Có lẽ không phải nhập khẩu cho hầu hết mọi người nhưng một số người trong chúng ta vẫn buộc phải làm việc trên UNIXen cổ :-) – paxdiablo

+4

Hãy coi chừng, điều này cũng thất bại trên dấu gạch ngang, đó là '/ bin/sh' trên nhiều Linux hiện đại. – phihag

5

Báo giá đơn là rất mạnh. Một khi bên trong, không có gì bạn có thể làm để gọi thay thế biến, cho đến khi bạn rời khỏi. Sử dụng dấu ngoặc kép thay vì:

echo $LINE | sed -e "s/12345678/$replace/g" 
-1

Tôi thích sử dụng dấu ngoặc kép, như quptes đơn là rất mạnh mẽ như chúng ta sử dụng chúng nếu không thể thay đổi bất cứ điều gì bên trong nó hoặc có thể gọi substituion biến.

vì vậy hãy sử dụng dấu ngoặc kép được instaed.

echo $LINE | sed -e "s/12345678/$replace/g" 
+4

Điều này có khác với câu trả lời của Dave (http://stackoverflow.com/a/6756853/2235132) không? – devnull

1

Để cho shell của bạn mở rộng biến, bạn cần phải sử dụng hai dấu ngoặc kép như

sed -i "s#12345678#$replace#g" file.txt 

này sẽ phá vỡ nếu $replace chứa đặc biệt sed ký tự (#, \).Nhưng bạn có thể xử lý trước $replace trích dẫn họ:

replace_quoted=$(printf '%s' "$replace" | sed 's/[#\]/\\\0/g') 
sed -i "s#12345678#$replace_quoted#g" file.txt 
7

Không cụ thể cho các câu hỏi, nhưng cho folks người cần cùng một loại chức năng mở rộng cho rõ ràng từ câu trả lời trước:

str="someFileName.foo" 
find=".foo" 
replace=".bar" 
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 
0

Sử dụng này để thay thế

echo $LINE | sed -e 's/12345678/$replace/g' 

này làm việc cho tôi chỉ đơn giản là loại bỏ các dấu ngoặc kép

Các vấn đề liên quan