Làm cho kết quả pwd trong điều khoản của ~ ~?


28

pwd đưa cho tôi

/data/users/me/some/random/folder

Có cách nào dễ dàng để có được

~/some/random/folder

từ pwdđâu


Là đường ống qua sed là một lựa chọn?
Matthew D. Scholefield

7
Nếu bạn đang đi để làm điều này, tôi muốn mạnh mẽ khuyên bạn đặt tên kết quả lệnh một cái gì đó khác hơn pwd. Mặt khác, bạn sẽ phá vỡ các tập lệnh mong muốn sử dụng đầu ra của nó trong các bối cảnh không thực hiện mở rộng dấu ngã.
Charles Duffy

Câu trả lời:


25

Nếu bạn đang sử dụng bash, thì dirsnội dung có hành vi mong muốn:

dirs +0
~/some/random/folder

(Lưu ý +0, không phải-0 .)

Với zsh:

dirs
~/some/random/folder

Để chính xác, trước tiên chúng ta cần xóa ngăn xếp thư mục, nếu không dirssẽ in tất cả nội dung:

dirs -c; dirs

Hoặc với zsh's printBUILTIN:

print -rD $PWD

hoặc là

print -P %~

(mà một biến mở rộng nhanh chóng trên. %~trong $PS1nở vào thư mục hiện với $HOMEthay thế bằng ~nhưng cũng xử lý khác thư mục có tên như thư mục chính của người dùng khác hoặc tên thư mục mà bạn đã xác định).


Tôi chuyển tất cả thời gian giữa bash và zsh. Thật không may, giải pháp này buộc tôi phải nhớ sự khác biệt giữa các vỏ và cũng phải nhớ (để kiểm tra) nơi tôi hiện đang ở. Câu trả lời của @Bichoy là bất khả tri cho hai người này.
avp

18

Bạn có thể sử dụng tính năng thay thế chuỗi con biến Bash:

$ pwd
/home/vagrant/foo/bar
$ echo ${PWD/#$HOME/'~'}
~/foo/bar

2
Điều này cũng hoạt động trong kshzsh.
mr.spuratic

1
Mặc dù tôi đã đưa ra câu trả lời này bởi vì đây là cách dễ nhất, có một cảnh báo nhỏ ở đây: bên trong / tmp / home / tên người dùng, điều này sẽ trả về / tmp ~. Tôi không thể tìm cách chèn dấu caret trước $ HOME để sửa lỗi này. Nếu bạn cần giải pháp của mình thật hoàn hảo, đừng sử dụng điều này ...
0fnt

1
@ user18151, hơn bạn đã chỉ ra điều này. Tôi đã thay thế câu trả lời của tôi thành ${string/#substring/replacement}phiên bản để ngăn chặn hành vi này.
Nykakin

1
@ mr.spuratic nó chỉ đúng (ngoại trừ việc sử dụng echo) trong zsh. Trong các shell khác, $HOMEsẽ được coi là một mô hình và toàn bộ điều có thể phân tách + global.
Stéphane Chazelas

Thoát khỏi dấu ngã ('~') đã thực hiện thủ thuật. Lưu ý rằng \ ~ cũng hoạt động. Điều này thuận tiện khi đã có trong '-tiếp theo: ví dụ:PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
Atafar

7

Sử dụng sed:

pwd | sed "s|^$HOME|~|"

Ý tưởng là sử dụng bất kỳ ký tự nào ít có khả năng xuất hiện trong đường dẫn thư mục chính làm dấu phân cách trong sedregex. Trong ví dụ trên tôi đang sử dụng |.

Điểm hay của kỹ thuật này là nó thực sự độc lập với vỏ.

Bạn cũng có thể bí danh pwdđể /bin/pwd | sed "s|$HOME|~|"có được hành vi này trong các tập lệnh khác có thể đang sử dụng pwd.


2
Bạn cần bao gồm các ^neo trong regex của bạn. Mặt khác, điều này có thể (tuy nhiên là không thể) để thay thế một đoạn ở giữa đường dẫn.
Sildoreth

Trên thực tế regex nên nhìn như sau "s|^/home/user\(/.*\)\?$|~\1|". Nếu không nó phù hợp với những con đường của người dùng khác nếu tên của họ cũng giống như user1, user2, user3và bạn kết hợp chỉuser
avp

3
tilde=\~${PWD#~}

Tôi nghĩ đó là những gì bạn muốn?

Điều gì gọn gàng về dấu ngã là khi nó được mở rộng như một mẫu mà nó không cần trích dẫn. Sử dụng $HOMEtheo cách tương tự mà không có dấu ngoặc kép sẽ cho kết quả không thể đoán trước bởi vì bất kỳ ký tự cấu thành nào của nó có thể là ký tự mẫu, và do đó, nó có thể không luôn luôn hiển thị kết quả như mong đợi.

Nhưng việc mở rộng dấu ngã được xác định là luôn luôn xảy ra như thể đó là kết quả của việc mở rộng được trích dẫn, và vì vậy kết quả của nó là có thể dự đoán được. Điều này dường như đúng trong thực tế mọi vỏ mà tôi đã thử nghiệm cho cả casemẫu và mẫu tham số với các ngoại lệ đáng chú ý của cả hai ksh93mkshvì bất kỳ lý do nào - dường như cả hai đều không tôn trọng khía cạnh được trích dẫn của dấu ngã trong khả năng đó.

Một điều thú vị khác về điều này là bạn có thể xác định lại $HOMEđể xử lý bất kỳ thư mục nào theo cùng một cách. Ví dụ:

cd ~
HOME=/some/prefix/I/would/like/to/trim 
#or, perhaps more usefully, some scripted means of arriving at same
tilde=\~${OLDPWD#~}
HOME=$PWD

Đây là một ví dụ khác:

set 1 2 3 4 5 \~
cd ~; cd -; HOME= IFS=/
for d do shift
      HOME=${*#~/}/$d
      set ~ "$d" $HOME
done; cd -; HOME=$PWD
printf %s\\n "$@"
5/4/3/2/1/2/3/4/5/~/1/2/3/4/5/~
~
5
4
3
2
1
2
3
4
5
~
1
2
3
4
5
~

1
Đó là một cách tiếp cận thực sự thú vị. Nhưng nó giả định rằng đó $PWDlà dưới $HOME. Bạn có thể sử dụng cùng một ý tưởng kết hợp với thay thế mẫu để làm cho nó tổng quát hơn. Làm thế nào là ${PWD/#~/\~}?
Mikel

1
Thật ra câu trả lời của Nykakin là cơ bản.
Mikel

0

Bạn có thể thử thay thế phần không mong muốn bằng sed:

pwd | sed 's,^/data/users/me,~,'

hoặc thậm chí tốt hơn:

pwd | sed "s,^$HOME,~,"

1
Bạn cần sử dụng ^neo để đảm bảo rằng chỉ khớp ở đầu đường dẫn thư mục được thay thế. Ngoài ra, bạn không cần sử dụng gvì lệnh sẽ thay thế tối đa 1 lần xuất hiện.
Sildoreth

Cảm ơn bạn. Tôi vẫn đang học những điều này và bạn nhận xét là thực sự hữu ích.
dùng1403360

Có vấn đề nếu thư mục nhà của tôi là /home/alicevà thư mục hiện tại của tôi là /home/aliceinchains. Nhưng nếu lần duy nhất tôi muốn sử dụng tính năng này là khi tôi biết tôi là thư mục chính của tôi hoặc một trong các thư mục con của nó, thì nó sẽ hoạt động.
Mihai Danila
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.