เช่นตรวจสอบว่า$PWD
เป็นไดเรกทอรีย่อยของ / home ในคำอื่น ๆ ที่ฉันกำลังค้นหาการดำเนินการสตริงทุบตีเพื่อตรวจสอบว่าหนึ่งสตริงเริ่มต้นด้วยอีก
เช่นตรวจสอบว่า$PWD
เป็นไดเรกทอรีย่อยของ / home ในคำอื่น ๆ ที่ฉันกำลังค้นหาการดำเนินการสตริงทุบตีเพื่อตรวจสอบว่าหนึ่งสตริงเริ่มต้นด้วยอีก
คำตอบ:
หากคุณต้องการทดสอบอย่างน่าเชื่อถือว่าไดเรกทอรีนั้นเป็นไดเรกทอรีย่อยของไดเรกทอรีอื่นหรือไม่คุณจะต้องมีมากกว่าการตรวจสอบคำนำหน้าสตริง คำตอบของ Gilles อธิบายโดยละเอียดเกี่ยวกับวิธีการทดสอบนี้อย่างถูกต้อง
แต่ถ้าคุณต้องการตรวจสอบคำนำหน้าสตริงอย่างง่าย (บางทีคุณอาจทำให้เส้นทางของคุณเป็นปกติ?) นี่เป็นวิธีที่ดี:
test "${PWD##/home/}" != "${PWD}"
หาก$PWD
เริ่มต้นด้วย "/ home /" มันจะถูกถอดออกทางด้านซ้ายซึ่งหมายความว่ามันจะไม่ตรงกับด้านขวาดังนั้น "! =" จะส่งกลับค่าจริง
${PWD/#$HOME/\~}
"${PWD%%/subdir*}"
เพื่อตรวจสอบว่าผู้ใช้อยู่ในsubdir
หรืออยู่ในไดเรกทอรีย่อยsubdir
เนื่องจาก %% จับจากจุดสิ้นสุดของสตริงแทนการเริ่มต้น สิ่งนี้จะเป็นประโยชน์สำหรับทุกคนที่กำลังมองหาข้อมูลเพิ่มเติมเกี่ยวกับการทดแทนพารามิเตอร์: tldp.org/LDP/abs/html/parameter-substitution.html
ในการทดสอบว่าสตริงนั้นเป็นคำนำหน้าของสตริงอื่นในเชลล์สไตล์ใดก็ตาม
case $PWD/ in
/home/*) echo "home sweet home";;
*) echo "away from home";;
esac
หลักการเดียวกันนี้ใช้สำหรับการทดสอบส่วนต่อท้ายหรือซับสตริง โปรดสังเกตว่าในcase
โครงสร้างเหมือนชื่อไฟล์*
ตรงกับตัวอักษรใด ๆ รวมถึงหรือเริ่มต้น/
.
ในเชลล์ที่ใช้[[ … ]]
ไวยากรณ์ (เช่น bash, ksh และ zsh) สามารถใช้เพื่อจับคู่สตริงกับรูปแบบ (โปรดทราบว่า[
คำสั่งสามารถทดสอบสตริงเพื่อความเท่าเทียมกันเท่านั้น)
if [[ $PWD/ = /home/* ]]; then …
หากคุณกำลังทดสอบว่าไดเรกทอรีปัจจุบันอยู่ภายใต้/home
หรือไม่การทดสอบสตริงย่อยแบบง่ายไม่เพียงพอเนื่องจากลิงก์สัญลักษณ์
หาก/home
เป็นระบบไฟล์ของตัวเองให้ทดสอบว่าไดเรกทอรีปัจจุบัน ( .
) อยู่ในระบบไฟล์นั้นหรือไม่
if [ "$(df -P . | awk 'NR==2 {print $6}')" = "/home" ]; then
echo 'The current directory is on the /home filesystem'
fi
หากคุณมี NetBSD, OpenBSD หรือ GNU (เช่น Linux) readlink
คุณสามารถใช้readlink -f
เพื่อตัดการเชื่อมโยงสัญลักษณ์จากพา ธ
case $(readlink -f .)/ in $(readlink -f /home)/*) …
มิฉะนั้นคุณสามารถใช้pwd
เพื่อแสดงไดเรกทอรีปัจจุบัน แต่คุณต้องระวังที่จะไม่ใช้เชลล์ในตัวถ้าเชลล์ของคุณติดตามcd
คำสั่งและเก็บชื่อที่คุณใช้ในการเข้าถึงไดเรกทอรีแทนที่จะเป็นตำแหน่ง "จริง"
case $(pwd -P 2>/dev/null || env PWD= pwd)/ in
"$(cd /home && { pwd -P 2>/dev/null || env PWD= pwd; })"/*) …
รุ่นน้ำมันดิบ:
[ ${PWD:0:6} = "/home/" ]
มีข้อเสียที่หนึ่งที่มีการนับตัวอักษรแรกและหนึ่งไม่สามารถแทนที่โดยสิ่งที่ทั่วไปเช่น/home/
$1
แก้ไข (ขอบคุณ @Michael) เพื่อให้การเปรียบเทียบทั่วไป$VAR
สามารถใช้งานได้
[ "${PWD:0:${#VAR}}" = $VAR ]
${#var}
คือความยาว$var
ดังนั้นคุณสามารถพูดคุยทั่วไปได้[ "${PWD:0:${#1}}" = "$1" ]
ฉันไม่เข้าใจคำถามที่ดีเกินไป แต่จะหาแม่ของ$ PWDdirname $PWD
ทำ หากต้องการค้นหาพาเรนต์ของพาเรนต์ให้รันdirname $(dirname $PWD)
และต่อไป ...
/
ที่จะทำงานเฉพาะในกรณีที่ผมรู้ว่าลึกมิฉะนั้นผมจะจบลงด้วย ตกลงฉันสามารถตรวจสอบซ้ำ แต่ไม่มีอะไรที่ง่ายกว่านี้หรือ
การใช้awk
:
echo $PWD | awk -v h="/home" '$0 ~ h {print "MATCH"}'
อืมมันน่าเสียดายที่[
ไม่มีตัวเลือกของSTRING1 starts with STRING2
เงื่อนไขการทดสอบ
คุณอาจลองecho $PWD | grep '^$VAR'
แต่อาจล้มเหลวในรูปแบบที่น่าสนใจเมื่อVAR
มีสัญลักษณ์พิเศษ
awk
ของindex
ฟังก์ชั่นควรจะสามารถทำเคล็ดลับ แต่ทั้งหมดนี้ดูเหมือนจะหนักเกินไปสำหรับสิ่งที่ง่ายต่อการทดสอบ
หากพบส่วนของเส้นทางที่พบฉัน "ว่าง" ตัวแปร:
[[ -z "${PWD//*\/home\/*/}" ]] && echo "toto"
[ "${PWD##$VAR}" != "$PWD" ]
และถ้านี่เป็น [code-golf] ( stackoverflow.com/questions/tagged/code-golf) คำถามคุณจะต้องเอาชนะฉันด้วยตัวอักษรสองตัว ;-) นอกจากนี้ยังมีลักษณะ อ่านได้มากขึ้น ...