Buat hasil pwd dalam istilah “~”?

28

pwd memberi saya

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

Apakah ada cara mudah untuk mendapatkan

~/some/random/folder

dari pwd?

Sibbs Gambling
sumber
Apakah pemipaan melalui sed merupakan opsi?
Matthew D. Scholefield
7
Jika Anda akan melakukan ini, saya sangat merekomendasikan memberi nama perintah yang dihasilkan selain pwd. Jika tidak, Anda akan memecahkan skrip yang berharap untuk menggunakan outputnya dalam konteks yang tidak melakukan ekspansi tilde.
Charles Duffy

Jawaban:

25

Jika Anda menggunakan bash, maka dirsbuiltin memiliki perilaku yang diinginkan:

dirs +0
~/some/random/folder

(Catatan +0, bukan-0 .)

Dengan zsh:

dirs
~/some/random/folder

Tepatnya, pertama-tama kita harus menghapus tumpukan direktori, kalau tidak dirsakan mencetak semua konten:

dirs -c; dirs

Atau dengan zsh's printbuiltin:

print -rD $PWD

atau

print -P %~

(yang mengaktifkan ekspansi prompt . %~di $PS1memperluas ke direktori saat ini dengan $HOMEdiganti dengan ~tetapi juga menangani direktori bernama lain seperti direktori home pengguna lain atau direktori bernama yang Anda tentukan sendiri).

kekacauan
sumber
Saya beralih sepanjang waktu antara bash dan zsh. Sayangnya solusi ini memaksa saya untuk mengingat perbedaan antara cangkang dan juga untuk mengingat (untuk memeriksa) keberadaan saya saat ini. Jawaban oleh @Bichoy adalah shell-agnostic untuk keduanya.
avp
18

Anda dapat menggunakan fitur penggantian substring variabel Bash:

$ pwd
/home/vagrant/foo/bar
$ echo ${PWD/#$HOME/'~'}
~/foo/bar
Nykakin
sumber
2
Ini juga berfungsi di kshdan zsh.
mr.spuratic
1
Walaupun saya telah memutakhirkan jawaban ini karena cara termudah, ada peringatan kecil di sini: di dalam / tmp / home / nama pengguna, ini akan mengembalikan / tmp ~. Saya tidak dapat menemukan cara untuk memasukkan tanda tanda sisipan sebelum $ HOME untuk memperbaikinya. Jika Anda membutuhkan solusi Anda untuk menjadi sempurna, jangan gunakan ini ...
0fnt
1
@ user18151, daripada Anda untuk menunjukkan ini. Saya mengganti jawaban saya ke ${string/#substring/replacement}versi untuk mencegah perilaku ini.
Nykakin
1
@ mr.spuratic hanya benar (kecuali untuk penggunaan echo) di zsh. Di kerang lain, $HOMEakan diperlakukan sebagai pola dan semuanya dapat dibagi + glob.
Stéphane Chazelas
Melarikan diri dari tilde ('~') berhasil. Perhatikan bahwa \ ~ juga berfungsi. Ini nyaman ketika sudah di '-context: eg,PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
Atafar
7

Menggunakan sed:

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

Idenya adalah untuk menggunakan karakter apa pun yang cenderung muncul di jalur direktori home sebagai pembatas di sedregex. Dalam contoh di atas saya menggunakan |.

Hal yang baik tentang teknik ini adalah ia sebenarnya tidak tergantung pada shell.

Anda juga bisa alias pwduntuk /bin/pwd | sed "s|$HOME|~|"mendapatkan perilaku ini di skrip lain yang mungkin menggunakan pwd.

Bichoy
sumber
2
Anda harus memasukkan ^jangkar di regex Anda. Kalau tidak, dimungkinkan (namun tidak mungkin) untuk mengganti segmen di tengah jalan.
Sildoreth
Sebenarnya regex harus terlihat sebagai berikut "s|^/home/user\(/.*\)\?$|~\1|". Jika tidak cocok jalur pengguna lain jika namanya seperti user1, user2, user3dan Anda cocok hanyauser
avp
3
tilde=\~${PWD#~}

Saya pikir itu yang Anda inginkan?

Yang rapi tentang tilde adalah ketika diperluas sebagai pola yang tidak perlu dikutip. Menggunakan $HOMEdengan cara yang sama tanpa tanda kutip itu akan memberikan hasil yang tidak dapat diprediksi karena salah satu karakter penyusunnya bisa berupa karakter pola, sehingga mungkin tidak selalu memberikan hasil yang diharapkan.

Tetapi ekspansi tilde ditentukan untuk selalu terjadi seolah-olah itu adalah hasil dari ekspansi yang dikutip, dan hasilnya dapat diprediksi. Hal ini tampaknya berlaku di hampir setiap shell yang telah saya uji untuk kedua casepola dan pola parameter dengan pengecualian keduanya ksh93dan mkshuntuk alasan apa pun - tak satu pun yang tampaknya menghormati aspek kutip dari tilde dalam kapasitas itu.

Hal lain yang rapi tentang ini adalah Anda dapat mendefinisikan ulang $HOMEuntuk menangani direktori apa pun dengan cara yang sama. Sebagai contoh:

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

Ini contoh lain:

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
~
mikeserv
sumber
1
Itu pendekatan yang sangat menarik. Tapi anggap itu di $PWDbawah $HOME. Anda bisa menggunakan ide yang sama dikombinasikan dengan substitusi pola untuk membuatnya lebih umum. Bagaimana ${PWD/#~/\~}?
Mikel
1
Sebenarnya jawaban Nykakin pada dasarnya adalah itu.
Mikel
0

Anda dapat mencoba mengganti bagian yang tidak diinginkan dengan sed:

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

atau bahkan lebih baik:

pwd | sed "s,^$HOME,~,"
pengguna1403360
sumber
1
Anda perlu menggunakan ^jangkar untuk memastikan bahwa hanya kecocokan di awal jalur direktori yang diganti. Juga, Anda tidak perlu menggunakan gkarena perintah harus mengganti paling banyak 1 kejadian.
Sildoreth
Terima kasih. Saya masih mempelajari hal-hal ini dan komentar Anda sangat membantu.
user1403360
Bermasalah jika direktori home saya dan direktori /home/alicesaya saat ini /home/aliceinchains. Tetapi jika satu-satunya waktu saya ingin menggunakan fitur ini adalah ketika saya tahu saya direktori home saya atau salah satu subdirektori, maka itu harus berfungsi.
Mihai Danila