ฉันจะได้รับเพียงแค่ชื่อไดเรกทอรีการทำงานปัจจุบันในสคริปต์ทุบตีหรือดีกว่าเพียงแค่คำสั่ง 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`"
xargs
formultion ไม่มีประสิทธิภาพและบักกี้เมื่อชื่อไดเรกทอรีมีการขึ้นบรรทัดใหม่หรืออักขระเครื่องหมายคำพูดและสูตรที่สองเรียก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)"
จะเป็นทั้งอ่านง่ายและยืดหยุ่นกับชื่อไดเรกทอรีที่มีช่องว่าง