ฉันจะได้รับเพียงแค่ชื่อไดเรกทอรีการทำงานปัจจุบันในสคริปต์ทุบตีหรือดีกว่าเพียงแค่คำสั่ง terminal
pwdให้เส้นทางแบบเต็มของไดเรกทอรีการทำงานปัจจุบันเช่น/opt/local/binแต่ฉันต้องการเท่านั้นbin
ฉันจะได้รับเพียงแค่ชื่อไดเรกทอรีการทำงานปัจจุบันในสคริปต์ทุบตีหรือดีกว่าเพียงแค่คำสั่ง terminal
pwdให้เส้นทางแบบเต็มของไดเรกทอรีการทำงานปัจจุบันเช่น/opt/local/binแต่ฉันต้องการเท่านั้นbin
คำตอบ:
ไม่จำเป็นต้องมีชื่อไฟล์และโดยเฉพาะอย่างยิ่งไม่จำเป็นต้องใช้ subshell ที่เรียกใช้ pwd (ซึ่งเป็นการเพิ่มการแยกแบบพิเศษและราคาแพง ); เชลล์สามารถทำได้ภายในโดยใช้การขยายพารามิเตอร์ :
result=${PWD##*/} # to assign to a variable
printf '%s\n' "${PWD##*/}" # to print to stdout
# ...more robust than echo for unusual names
# (consider a directory named -e or -n)
printf '%q\n' "${PWD##*/}" # to print to stdout, quoted for use as shell input
# ...useful to make hidden characters readable.
โปรดทราบว่าหากคุณใช้เทคนิคนี้ในสถานการณ์อื่น ๆ (ไม่ใช่PWDแต่ตัวแปรอื่น ๆ ที่มีชื่อไดเรกทอรี) คุณอาจต้องตัดเครื่องหมายสแลชต่อท้าย ด้านล่างใช้การสนับสนุน extglobของ bash เพื่อทำงานแม้จะมีเครื่องหมายทับหลาย ๆ
dirname=/path/to/somewhere//
shopt -s extglob # enable +(...) glob syntax
result=${dirname%%+(/)} # trim however many trailing slashes exist
result=${result##*/} # remove everything before the last / that still remains
printf '%s\n' "$result"
อีกทางเลือกหนึ่งโดยไม่มีextglob:
dirname="/path/to/somewhere//"
result="${dirname%"${dirname##*[!/]}"}" # extglob-free multi-trailing-/ trim
result="${result##*/}" # remove everything before the last /
$PWDเป็นชื่อของตัวแปร bash ในตัว; ชื่อตัวแปรในตัวทั้งหมดอยู่ในตัวพิมพ์ใหญ่ทั้งหมด (เพื่อแยกความแตกต่างจากตัวแปรท้องถิ่นซึ่งควรมีอักขระตัวพิมพ์เล็กอย่างน้อยหนึ่งตัว) result=${PWD#*/}ไม่ได้ประเมิน/full/path/to/directory; แต่จะแยกเฉพาะองค์ประกอบแรกpath/to/directoryเท่านั้น การใช้#อักขระสองตัวทำให้รูปแบบจับคู่โลภจับคู่กับตัวละครให้ได้มากที่สุด อ่านหน้าการขยายพารามิเตอร์เชื่อมโยงในคำตอบเพิ่มเติม
pwdอาจไม่เหมือนกันเสมอกับค่าของ$PWDเนื่องจากความยุ่งยากที่เกิดจากcdไอเอ็นจีผ่านลิงก์สัญลักษณ์ไม่ว่าทุบตีมีการ-o physicalตั้งค่าตัวเลือกและอื่น ๆ สิ่งนี้เคยเป็นสิ่งที่น่ารังเกียจเป็นพิเศษเกี่ยวกับการจัดการไดเรกทอรีอัตโนมัติซึ่งการบันทึกเส้นทางทางกายภาพแทนที่จะเป็นตรรกะจะสร้างเส้นทางที่ถ้าใช้จะอนุญาตให้ตัวนับอัตโนมัติลงจากไดเรกทอรีที่ใช้งานอยู่
shและcshและหากคุณต้องการที่ปุ่ม Backspace ในการทำงานคุณต้องอ่านทั้งsttyหน้าคนและเราชอบมัน!"
ใช้basenameโปรแกรม สำหรับกรณีของคุณ:
% basename "$PWD"
bin
basenameโปรแกรมใช่หรือไม่ มีอะไรผิดปกติกับคำตอบนี้นอกจากคำพูดที่หายไป?
basenameย่อมเป็นโปรแกรมภายนอกว่าจะเป็นสิ่งที่ถูกต้อง แต่การทำงานใด ๆโปรแกรมภายนอกสำหรับทุบตีสิ่งที่สามารถทำออกจากกล่องโดยใช้ฟังก์ชันในตัวเดียวคือโง่ที่เกิดขึ้นส่งผลกระทบต่อผลการดำเนินงาน ( fork(), execve(), wait()ฯลฯ ) สำหรับ ไม่มีเหตุผล.
basenameที่นี่ใช้ไม่ได้dirnameเพราะdirnameมีฟังก์ชั่นที่${PWD##*/}ไม่ได้ - แปลงสตริงที่ไม่มีเครื่องหมายทับเพื่อ.เป็นต้น ดังนั้นในขณะที่ใช้dirnameเป็นเครื่องมือภายนอกมีค่าใช้จ่ายด้านประสิทธิภาพ แต่ก็มีฟังก์ชั่นที่ช่วยชดเชยได้เหมือนกัน
functionคำหลัก POSIX- เข้ากันไม่ได้โดยไม่ต้องเพิ่มค่าใด ๆ ในไวยากรณ์มาตรฐานและการขาดคำพูดจะสร้างข้อบกพร่องในชื่อไดเรกทอรีที่มีช่องว่าง wdexec() { "./$(basename "$PWD")"; }อาจเป็นทางเลือกที่ดีกว่า
basenameมีประสิทธิภาพน้อยกว่า แต่มันอาจมีประสิทธิภาพมากกว่าในแง่ของประสิทธิภาพการทำงานของนักพัฒนาเพราะมันง่ายต่อการจดจำเมื่อเปรียบเทียบกับไวยากรณ์ bash ที่น่าเกลียด ดังนั้นถ้าคุณจำมันไปได้เลย มิฉะนั้นbasenameทำงานได้เช่นกัน มีใครเคยต้องปรับปรุง "ประสิทธิภาพ" ของสคริปต์ทุบตีและทำให้มีประสิทธิภาพมากขึ้นหรือไม่
$ echo "${PWD##*/}"
echo "${PWD##*/}"การใช้งานที่ถูกต้องจะเป็น
name=${PWD##*/}จะถูกต้องและname=$(echo "${PWD##*/}")จะผิด (ในแง่ที่ไร้ประสิทธิภาพ)
คุณสามารถใช้การรวมกันของ pwd และ basename เช่น
#!/bin/bash
CURRENT=`pwd`
BASENAME=`basename "$CURRENT"`
echo "$BASENAME"
exit;
วิธีการเกี่ยวกับ grep:
pwd | grep -o '[^/]*$'
pwd | xargs basenameไม่ได้ .. อาจจะสำคัญไม่ว่า แต่คำตอบอื่น ๆ ที่เป็นที่เรียบง่ายและสอดคล้องกันมากขึ้นในสภาพแวดล้อม
ฉันชอบคำตอบที่เลือก (Charles Duffy) แต่ระวังถ้าคุณอยู่ใน dir symlinked และคุณต้องการชื่อของ dir เป้าหมาย น่าเสียดายที่ฉันไม่คิดว่าสามารถทำได้ในนิพจน์การขยายพารามิเตอร์เดียวบางทีฉันเข้าใจผิด สิ่งนี้น่าจะใช้ได้:
target_PWD=$(readlink -f .)
echo ${target_PWD##*/}
หากต้องการดูสิ่งนี้การทดลอง:
cd foo
ln -s . bar
echo ${PWD##*/}
รายงาน "แถบ"
ในการแสดงไดเร็กทอรีชั้นนำของพา ธ (โดยไม่เกิดการแยก fork-exec ของ / usr / bin / dirname):
echo ${target_PWD%/*}
เช่นจะแปลง foo / bar / baz -> foo / bar
readlink -fเป็นส่วนขยายของ GNU และไม่สามารถใช้ได้ใน BSD (รวมถึง OS X)
echo "$PWD" | sed 's!.*/!!'
หากคุณกำลังใช้เชลล์เป้าหมายหรือ${PWD##*/}ไม่พร้อมใช้งาน
${PWD##*/}คือ POSIX sh - ทุกทันสมัย / bin / sh (รวมถึงเส้นประเถ้า ฯลฯ ) สนับสนุน หากต้องการชมบอร์นที่เกิดขึ้นจริงในกล่องล่าสุดคุณจะต้องอยู่ในระบบโซลาริสเก่า ๆ นอกเหนือจากนั้น - echo "$PWD"; การไม่ใส่เครื่องหมายอัญประกาศนำไปสู่ข้อบกพร่อง (หากชื่อไดเรกทอรีมีช่องว่างอักขระตัวแทน ฯลฯ )
หัวข้อนี้ดีมาก! นี่คืออีกหนึ่งรสชาติ:
pwd | awk -F / '{print $NF}'
น่าแปลกที่ไม่มีใครพูดถึงตัวเลือกนี้ที่ใช้คำสั่ง bash ในตัวเท่านั้น:
i="$IFS";IFS='/';set -f;p=($PWD);set +f;IFS="$i";echo "${p[-1]}"
ในฐานะโบนัสที่เพิ่มเข้ามาคุณสามารถได้รับชื่อของไดเรกทอรีหลักด้วย:
[ "${#p[@]}" -gt 1 ] && echo "${p[-2]}"
สิ่งเหล่านี้จะใช้ได้กับ Bash 4.3-alpha หรือใหม่กว่า
ใช้:
basename "$PWD"
หรือ
IFS=/
var=($PWD)
echo ${var[-1]}
หมุน Internal Filename Separator (IFS) กลับไปเป็นช่องว่าง
IFS=
มีช่องว่างหนึ่งช่องหลังจาก IFS
basename $(pwd)
หรือ
echo "$(basename $(pwd))"
pwdเป็นสตริงแยกและ glob basenameขยายตัวก่อนที่จะถูกส่งผ่านไปยัง
basename "$(pwd)"- แต่ที่ไม่มีประสิทธิภาพมากเมื่อเทียบกับเพียงbasename "$PWD"ซึ่งเป็นตัวเองที่ไม่มีประสิทธิภาพเทียบกับการใช้การขยายตัวพารามิเตอร์แทนการโทรศัพท์basenameที่ทุกคน
สำหรับจ๊อกกี้พบที่นั่นเช่นฉัน:
find $PWD -maxdepth 0 -printf "%f\n"
$PWDไป"$PWD"เป็นจัดการชื่อไดเรกทอรีผิดปกติอย่างถูกต้อง
ฉันมักจะใช้สิ่งนี้ในสคริปต์ sh
SCRIPTSRC=`readlink -f "$0" || echo "$0"`
RUN_PATH=`dirname "${SCRIPTSRC}" || echo .`
echo "Running from ${RUN_PATH}"
...
cd ${RUN_PATH}/subfolder
คุณสามารถใช้สิ่งนี้เพื่อทำสิ่งต่าง ๆ โดยอัตโนมัติ ...
grep ด้านล่างด้วย regex ยังทำงานได้
>pwd | grep -o "\w*-*$"
เพียงใช้:
pwd | xargs basename
หรือ
basename "`pwd`"
xargsformultion ไม่มีประสิทธิภาพและบักกี้เมื่อชื่อไดเรกทอรีมีการขึ้นบรรทัดใหม่หรืออักขระเครื่องหมายคำพูดและสูตรที่สองเรียกpwdคำสั่ง ในเชลล์ย่อยแทนที่จะดึงผลลัพธ์เดียวกันผ่านการขยายตัวแปรในตัว
หากคุณต้องการดูเฉพาะไดเรกทอรีปัจจุบันในภูมิภาคของ bash prompt คุณสามารถแก้ไข.bashrcไฟล์~ได้ เปลี่ยน\wเป็น\Wในบรรทัด:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
วิ่ง source ~/.bashrcและจะแสดงเฉพาะชื่อไดเรกทอรีในพื้นที่พรอมต์
Ref: /superuser/60555/show-only-current-directory-name-not-full-path-on-bash-prompt
คุณสามารถใช้ยูทิลิตี้ basename ซึ่งจะลบคำนำหน้าใด ๆ ที่ลงท้ายด้วย / และคำต่อท้าย (หากมีอยู่ในสตริง) จากสตริงและพิมพ์ผลลัพธ์บนเอาต์พุตมาตรฐาน
$basename <path-of-directory>
ฉันชอบที่จะใช้gbasenameซึ่งเป็นส่วนหนึ่งของ coreutils GNU
basenameมี โดยทั่วไปจะเรียกเฉพาะgbasenameใน MacOS และแพลตฟอร์มอื่น ๆ ที่มาพร้อมกับชื่อที่ไม่ใช่ GNU
คำสั่งต่อไปนี้จะส่งผลให้พิมพ์ไดเรกทอรีทำงานปัจจุบันของคุณในสคริปต์ทุบตี
pushd .
CURRENT_DIR="`cd $1; pwd`"
popd
echo $CURRENT_DIR
$1จะมีไดเรกทอรีทำงานปัจจุบัน (2) pushdและpopdไม่มีจุดประสงค์ที่นี่เพราะสิ่งที่อยู่ภายใน backticks จะทำใน subshell - ดังนั้นมันไม่สามารถส่งผลกระทบต่อไดเรกทอรีของเปลือกแม่เริ่มต้นด้วย (3) การใช้"$(cd "$1"; pwd)"จะเป็นทั้งอ่านง่ายและยืดหยุ่นกับชื่อไดเรกทอรีที่มีช่องว่าง