Sử dụng sed trên một biến chuỗi chứ không phải là một tập tin


30

Tôi đã nói rằng điều đó là có thể, nhưng không có một ví dụ hoạt động nào, sedcó thể đọc từ một biến chuỗi mà không cần tệp đầu vào. Tôi vẫn chưa làm cho nó hoạt động. Để an toàn chung, tôi đang viết $PATHbiến này sang biến khác, vì tôi gặp rắc rối với điều này, vì tôi không cần phải phát sinh vấn đề khác cho đến khi tôi biết chính xác cách thực hiện.

Hãy xem xét những điều sau đây:

~$x=$PATH
~$sed -i 's/:/ /g' $x

Điều này không thành công với: Không có tập tin hoặc thư mục như vậy.

Đây là một số người khác tôi đã thử:

~$ sed -i 's/:/ /g' | (read x) 
sed: no input files
~$ sed -i 's/:/ /g' | (read $x) 
bash: read: `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
sed: no input files
~$ sed -i 's/:/ /g' | $(read x) 
sed: no input files
~$ sed -i 's/:/ /g' | $(read $x) 
bash: read: `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
sed: no input files
~$ sed -i 's/:/ /g' < $(read $x) 
bash: read: `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
bash: $(read $x): ambiguous redirect
~$ sed -i 's/:/ /g' < read $x 
bash: read: No such file or directory
~$ sed -i 's/:/ /g' < (read x) 
bash: syntax error near unexpected token `('
~$ sed -i 's/:/ /g' < $((read x)) 
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: syntax error: operand expected (error token is "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
~$ sed -i 's/:/ /g' < $((read $x)) 
bash: read /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: division by 0 (error token is "usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
~$ sed -i 's/:/ /g' << $((read $x)) 
> ;^C
~$ sed -i 's/:/ /g' << $(read $x)
> ;^C
~$ sed -i 's/:/ /g' $x
sed: can't read /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
~$ sed -i 's/:/ /g' < $x
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
~$ sed -i 's/:/ /g' < echo $x
bash: echo: No such file or directory
~$ sed -i 's/:/ /g' |  echo $x
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
sed: no input files

Điều này thậm chí có thể làm việc? Tôi không muốn viết các tập tin mà tôi không cần chỉ để tôi có thể sử dụng sed. Đối với ví dụ cụ thể này, nếu ~$x=$PATH ~$sed -i 's/:/ /g' $xthực sự hoạt động theo cách tôi mong muốn, tôi sẽ nhận được:

/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games

mà sau đó tôi có thể gán cho một biến và sử dụng trong các lệnh trong tương lai, như ls $x


1
x=$(echo "$x" | sed 's/:/ /g')?
heemayl 10/03/2015

Câu trả lời:


16

Có lẽ:

~$ x="$PATH"
~$ x="$(echo $x | sed 's/:/ /g')"
~$ echo "$x"
/usr/local/bin /usr/bin /bin /usr/local/games /usr/games

@jOh --- lưu ý rằng sedở đây không hoạt động trên "biến chuỗi" (?), nhưng trên đầu vào tiêu chuẩn --- đó là cách nó phải như vậy.
Rmano 10/03/2015

tôi nghĩ Ill thực hiện một yêu cầu tính năng cho các nhà phát triển sed
j0h

4
@ j0h điều này không liên quan gì sed, đó là câu hỏi làm thế nào shell chuyển hướng đầu vào. sedgiao dịch với các luồng đầu vào và nó đọc chúng thông qua đầu vào tiêu chuẩn của nó. Cho dù chúng là tập tin hay không là không liên quan. Nó có thể chấp nhận bất cứ điều gì miễn là thông qua đầu vào tiêu chuẩn.
terdon

38

Điều này không có gì để làm sednhư vậy, nó áp dụng cho bất kỳ chương trình đọc đầu vào tiêu chuẩn. Dù sao, những gì bạn đang tìm kiếm là

sed 's/:/ /g' <<<"$PATH"

Không có lý do để lưu trong một biến khác, không có gì bạn làm theo cách này sẽ ảnh hưởng đến giá trị được lưu trữ trong biến đó. Bạn cần toán tử gán ( =) cho điều đó. Cú pháp được sử dụng ở trên được gọi là "chuỗi ở đây" và dành riêng cho bash, ksh và zsh. Nó phục vụ để chuyển giá trị của một biến làm đầu vào cho một chương trình đọc từ đầu vào tiêu chuẩn.

Tôi đã viết một câu trả lời trên U & L liệt kê tất cả các toán tử shell khác nhau như cái này. Bạn có thể muốn có một cái nhìn.

Lưu ý rằng bạn cũng có thể đã làm

echo "$PATH" | sed 's/:/ /g' 

Cuối cùng, bạn thực sự không cần sedchút nào cho việc này. Bạn có thể làm toàn bộ điều trong bash trực tiếp:

echo "${PATH//:/ }"

Trên đây là một cấu trúc thay thế bash. Cho một biến $var, một mô hình patvà một sự thay thế ( rep), để thay thế tất cả các lần xuất hiện của patrep, bạn sẽ làm gì

echo "${var//pat/rep}"

Điều tương tự với một dấu gạch chéo chỉ thay thế lần xuất hiện đầu tiên:

echo "${var/pat/rep}"

2
Cảm ơn vì 'bash thay thế xây dựng'. Tôi đã có thể sử dụng: "$ {1 / from / to}" trong hàm Bash để thay đổi đối số đầu tiên thành các tham số tiếp theo.
Câu lạc bộ AAAfarm
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.