ทำให้ pwd ส่งผลในแง่ของ“ ~”


28

pwd ให้ฉัน

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

มีวิธีง่าย ๆ ในการรับ

~/some/random/folder

จากpwdไหน


ตัวเลือกท่อผ่าน sed หรือไม่?
Matthew D. Scholefield

7
หากคุณกำลังจะทำเช่นนี้ผมขอpwdแนะนำให้ตั้งชื่อสิ่งที่ส่งผลให้คำสั่งอื่นที่ไม่ใช่ มิฉะนั้นคุณจะทำลายสคริปต์ที่คาดว่าจะใช้ผลลัพธ์ในบริบทที่ไม่ได้ดำเนินการขยายตัวหนอน
Charles Duffy

คำตอบ:


25

หากคุณกำลังใช้ bash แสดงว่าdirsbuiltin มีพฤติกรรมที่ต้องการ:

dirs +0
~/some/random/folder

(หมายเหตุ+0ไม่ใช่-0 )

ด้วยzsh:

dirs
~/some/random/folder

ก่อนอื่นเราต้องเคลียร์ไดเรกทอรีสแต็กมิฉะนั้นdirsจะพิมพ์เนื้อหาทั้งหมด:

dirs -c; dirs

หรือzsh's printbuiltin:

print -rD $PWD

หรือ

print -P %~

(ที่หนึ่งเปิดขยายพร้อมท์ . %~ใน$PS1ขยายไปยังไดเรกทอรีปัจจุบันด้วย$HOMEแทนที่ด้วย~แต่ยังจัดการไดเรกทอรีที่มีชื่ออื่น ๆเช่นไดเรกทอรีบ้านของผู้ใช้รายอื่นหรือไดเรกทอรีที่มีชื่อที่คุณกำหนดเอง)


ฉันสลับตลอดเวลาระหว่าง bash และ zsh น่าเสียดายที่โซลูชันนี้บังคับให้ฉันต้องจดจำความแตกต่างระหว่างกระสุนและจำ (เพื่อตรวจสอบ) ที่ฉันอยู่ในปัจจุบัน คำตอบโดย @Bichoy เป็นผู้ไม่เชื่อเรื่องพระเจ้าสำหรับสองคนนี้
avp

18

คุณสามารถใช้คุณสมบัติการแทนที่สตริงย่อย Bash:

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

2
นอกจากนี้ยังทำงานในและksh zsh
mr.spuratic

1
ในขณะที่ฉัน upvote คำตอบนี้เพราะวิธีที่ง่ายที่สุดมีข้อแม้เล็ก ๆ อยู่ที่นี่: ภายใน / tmp / home / ชื่อผู้ใช้นี้จะส่งคืน / tmp ~ ฉันไม่สามารถหาวิธีแทรกเครื่องหมายคาเร็ตก่อน $ HOME เพื่อแก้ไขปัญหานี้ได้ หากคุณต้องการโซลูชันที่สมบูรณ์แบบอย่าใช้สิ่งนี้ ...
0fnt

1
@ user18151 มากกว่าที่คุณจะชี้ให้เห็น ฉันเปลี่ยนคำตอบเป็น${string/#substring/replacement}เวอร์ชันเพื่อป้องกันพฤติกรรมนี้
Nykakin

1
@ mr.spuratic มันถูกต้องเท่านั้น (ยกเว้นสำหรับการใช้งานของecho) zshใน ในเปลือกหอยอื่น ๆ$HOMEจะถือว่าเป็นรูปแบบและสิ่งทั้งหมดที่อยู่ภายใต้การแยก + glob
Stéphane Chazelas

การหลบหนี tilde ('~') ก็เป็นการหลอกลวง โปรดทราบว่า \ ~ ยังใช้งานได้ สะดวกเมื่ออยู่ใน '-context: เช่นPROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"'
Atafar

7

การใช้sed:

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

แนวคิดคือการใช้อักขระใด ๆ ที่มีโอกาสน้อยที่จะปรากฏในพา ธ โฮมไดเร็กทอรีเป็นตัวคั่นในsedregex |ในตัวอย่างข้างต้นผมใช้

สิ่งที่ดีเกี่ยวกับเทคนิคนี้คือมันเป็นอิสระจากเปลือก

นอกจากนี้คุณยังสามารถตั้งชื่อpwdเพื่อ/bin/pwd | sed "s|$HOME|~|"รับพฤติกรรมนี้ในสคริปต์อื่น ๆ ที่อาจใช้งานpwdอยู่


2
คุณต้องรวม^จุดยึดใน regex ของคุณ มิฉะนั้นเป็นไปได้ (แต่ไม่น่าเป็นไปได้) ที่จะแทนที่ส่วนที่อยู่ตรงกลางของเส้นทาง
Sildoreth

ที่จริง regex "s|^/home/user\(/.*\)\?$|~\1|"ควรมีลักษณะดังต่อไปนี้ มิฉะนั้นมันตรงกับเส้นทางที่ผู้ใช้คนอื่นถ้าชื่อของพวกเขาเป็นเหมือนuser1, user2, user3และคุณตรงกับเพียงuser
AVP

3
tilde=\~${PWD#~}

ฉันคิดว่านั่นคือสิ่งที่คุณต้องการ?

สิ่งที่เรียบร้อยเกี่ยวกับตัวหนอนคือเมื่อมันถูกขยายออกเป็นลวดลายมันไม่จำเป็นต้องมีการอ้างอิง การใช้$HOMEวิธีเดียวกันโดยไม่มีเครื่องหมายคำพูดจะทำให้เกิดผลลัพธ์ที่คาดเดาไม่ได้เนื่องจากอักขระที่เป็นองค์ประกอบใด ๆ อาจเป็นอักขระรูปแบบและอาจไม่ได้ผลลัพธ์ที่คาดหวังเสมอไป

แต่การขยายตัวของตัวหนอนนั้นจะเกิดขึ้นเสมอราวกับว่ามันเป็นผลมาจากการขยายตัวที่ยกมาและเพื่อให้ผลลัพธ์ที่สามารถคาดการณ์ได้ สิ่งนี้ดูเหมือนว่าจะเป็นจริงในทุก ๆ เชลล์ที่ฉันทดสอบทั้งcaseรูปแบบและรูปแบบพารามิเตอร์โดยมีข้อยกเว้นที่น่าทึ่งของทั้งสองksh93และmkshไม่ว่าด้วยเหตุผลใด - ซึ่งดูเหมือนจะไม่ให้เกียรติในแง่มุมของเครื่องหมายตัวหนอน

อีกสิ่งที่เรียบร้อยเกี่ยวกับเรื่องนี้คือคุณสามารถกำหนดใหม่$HOMEเพื่อจัดการไดเรกทอรีใด ๆ ในแบบเดียวกัน ตัวอย่างเช่น:

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

นี่เป็นอีกตัวอย่าง:

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
นั่นเป็นวิธีที่น่าสนใจจริงๆ แต่สันนิษฐานว่าอยู่ภายใต้การ$PWD $HOMEคุณสามารถใช้แนวคิดเดียวกันรวมกับการแทนที่รูปแบบเพื่อทำให้เป็นเรื่องทั่วไปมากขึ้น เป็น${PWD/#~/\~}อย่างไร
Mikel

1
จริงๆแล้วคำตอบของ Nykakin นั้นเป็นแบบนั้น
Mikel

0

คุณสามารถลองเปลี่ยนชิ้นส่วนที่ไม่ต้องการด้วยsed:

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

หรือดีกว่า:

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

1
คุณต้องใช้^จุดยึดเพื่อให้แน่ใจว่าการจับคู่ที่จุดเริ่มต้นของเส้นทางไดเรกทอรีจะถูกแทนที่เท่านั้น นอกจากนี้คุณไม่จำเป็นต้องใช้gเพราะคำสั่งควรแทนที่ 1 เหตุการณ์ที่เกิดขึ้นมากที่สุด
Sildoreth

ขอขอบคุณ. ฉันยังคงเรียนรู้สิ่งนี้และคุณแสดงความคิดเห็นมีประโยชน์จริงๆ
user1403360

มีปัญหาถ้าไดเรกทอรีบ้านของฉันคือและไดเรกทอรีปัจจุบันของฉันคือ/home/alice /home/aliceinchainsแต่ถ้าครั้งเดียวที่ฉันต้องการใช้ฟีเจอร์นี้คือเมื่อฉันรู้ว่าฉันคือโฮมไดเร็กตอรี่ของฉันหรือหนึ่งในไดเร็กตอรี่ย่อยของมัน, มันน่าจะใช้ได้.
หมดเวลา Danila
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.