คุณสามารถทำได้เช่น:
cd /usr///.//share/../share//man/man1 || exit
IFS=/; set -f
printf %.1s/ ${PWD%/*}
printf %s\\n "${PWD##*/}"
/u/s/m/man1
และนี่คือsed
:
printf %s "$file" |
tr /\\n \\n/ | sed -et$ \
-e '\|^\.\.$|{x;s|\(.*\)\n.*$|\1|;x;}' \
-e 's|^\.\{0,2\}$||;\|.|H;$!d;x' \
-e$ -e '\|\(\.\{0,2\}.\)\(.*\)\(\n\)|!b' \
-e 's||\1\3\2\3|;P;s|\n||;D' |
tr /\\n \\n/
ซึ่งค่อนข้างใกล้เคียงกับการทำสิ่งเดียวกันทั้งหมดที่ฟังก์ชั่นทำอยู่ด้านล่าง มันไม่ได้ย่อด้วยตัวหนอนหรือใส่$PWD
หัวเพื่อนำไปสู่การไม่ - สแลชฟังก์ชั่น(และในความเป็นจริงไม่เคยพิมพ์เฉือนนำ)แต่ที่สามารถจัดการได้ในภายหลัง มันจะประมวลผลองค์ประกอบเส้นทางที่เป็นโมฆะและจุดเดียวและกำจัด..
กรณีและปัญหา
กำหนดman
เส้นทางเดียวกันกับcd
ด้านบนมันพิมพ์:
u/s/m/man1
มันจะพิมพ์จุดนำหน้าหนึ่งหรือสองพิเศษสำหรับแต่ละองค์ประกอบของพา ธ ที่ขึ้นต้นด้วยเช่นนั้นและไม่ใช่แค่หนึ่งหรือสองจุด
.
ที่คุณถามเกี่ยวกับการทำมากขึ้นกว่าตัวละครตัวหนึ่งสำหรับการเริ่มต้นเส้นทางองค์ประกอบด้วย ที่จะทำฉันคิดว่าแต่ละองค์ประกอบจะต้องการความสนใจเป็นรายบุคคลอยู่แล้วและเพราะฉันอยากรู้อยากเห็นฉันพยายามมือของฉันในการทำงานเส้นทางที่ยอมรับโดยไม่มีไดเรกทอรีการเปลี่ยนแปลง หลังจากลองผิดลองถูกในที่สุดฉันก็ตัดสินใจวิธีเดียวที่จะทำถูกต้องคือทำสองครั้ง - ย้อนหลังและส่งต่อ:
pathbytes(){
local IFS=/ o="$-" p
set -f${ZSH_VERSION+LFy}
set -- ${1:-$PWD}
for p in /${1:+$PWD} $*
do case $p in (.|"") ;;
(..) ${1+shift} ;;
(/) set -- ;;
(*) set -- $p $*; esac
done
for p in //$* ""
do case ${p:-/$3} in
([!./]*) ;;
(..*) set "..$@" ;;
(.*) set ".$@" ;;
(//*) ! set "" $1 $1 ;;
(~) ! p=\~ ;;
(~/*) p="~/$2";set $HOME
! while "${2+shift}" 2>&3
do p="~/${p#??*/}"
done 3>/dev/null;;
esac&& set "" "${p%"${p#$1?}"}/$2" "$p/$3"
done; printf %s\\n "${p:-$2}"
set +f "-${o:--}"
}
ดังนั้นจึงไม่เคยเปลี่ยนไดเรกทอรีหรือพยายามยืนยันการมีอยู่ขององค์ประกอบเส้นทางใด ๆ แต่มันบีบ/
ตัวคั่นซ้ำและวาง/./
องค์ประกอบจุดเดียวทั้งหมดและประมวลผล/../
องค์ประกอบจุดคู่ที่เหมาะสม
เมื่อ$IFS
ตั้งค่าเป็นอักขระที่ไม่ใช่ช่องว่างบางตัวลำดับของ$IFS
อักขระสองตัวหรือมากกว่านั้นจะส่งผลให้เกิดช่องว่างอย่างน้อยหนึ่งช่อง เครื่องหมายทับที่ต่อเนื่องกันหลายตัวทำงานกับอาร์กิวเมนต์ที่มีค่าเป็น null เช่นเดียวกับ$IFS
ตัวละครนำ และดังนั้นเมื่อset -- $1
แยกถ้าผล$1
เป็นโมฆะแล้วมันเริ่มต้นด้วยการเฉือนอื่นถ้ามันไม่ได้เป็นโมฆะแล้วใส่ฉัน${1:+$PWD}
$PWD
กล่าวอีกนัยหนึ่งถ้าอาร์กิวเมนต์แรกไม่ได้เริ่มต้นด้วยสแลชมันจะได้รับการ$PWD
เสริม ที่ใกล้เคียงเช่นนี้มาถึงเส้นทางการตรวจสอบ
มิฉะนั้นการfor
วนซ้ำครั้งแรกจะสลับลำดับของส่วนประกอบพา ธ ซ้ำเช่น:
1 2 3
1 2 3
2 1 3
3 2 1
... ในขณะที่ทำเช่นนั้นมันจะไม่สนใจองค์ประกอบจุดเดียวหรือโมฆะและสำหรับ..
...
1 .. 3
1 .. 3
3
3
... ผ่านสองฝืนผลกระทบนี้และในขณะที่ทำเช่นนั้นได้บีบแต่ละองค์ประกอบทั้ง2 จุด + ถ่านหรือ1 จุดถ่าน +หรือถ่าน
ดังนั้นจึงควรทำงานกับเส้นทางที่ยอมรับโดยไม่คำนึงถึงการดำรงอยู่
ฉันเพิ่ม / ลบออกเล็กน้อยในลูปที่สอง ตอนนี้set
s มักจะน้อย(เพียงครั้งเดียวสำหรับแต่ละ[!./]*
องค์ประกอบ)และสั้นวงจรcase
การประเมินผลรูปแบบมากที่สุดของเวลา(ขอบคุณรูปแบบดังกล่าวข้างต้น)~
และรวมถึงหางโทรตรงกับการประเมินผล หากส่วนทั้งหมดหรือส่วนนำ(แบ่งตามส่วนประกอบทั้งหมด)ของเส้นทางที่ยอมรับในที่สุดสามารถจับ~
คู่บิตที่ตรงกันจะถูกถอดออกและตัวอักษร~
จะถูกแทนที่ เพื่อที่จะทำเช่นนี้และฉันได้เพื่อรักษาฉบับเต็มของเส้นทางข้างที่ยากเช่นกัน(เพราะตรงกับเส้นทางที่ยากที่จะ~
อาจจะไม่เป็นประโยชน์มาก)และอื่น ๆ $3
นี้จะถูกเก็บไว้ใน สุดท้ายwhile
branch branch จะทำงานหาก~
ถูกจับคู่เป็นเซตย่อย$3
เท่านั้น
หากคุณset -x
เปิดใช้งานโดยเปิดใช้งานการติดตามคุณสามารถดูการทำงานได้
$ (set -x;pathbytes ..abc/def/123///././//.././../.xzy/mno)
+ pathbytes ..abc/def/123///././//.././../.xzy/mno
+ local IFS=/ o=xsmi p
+ set -f
+ set -- ..abc def 123 . . .. . .. .xzy mno
+ set --
+ set -- home
+ set -- mikeserv home
+ set -- ..abc mikeserv home
+ set -- def ..abc mikeserv home
+ set -- 123 def ..abc mikeserv home
+ shift
+ shift
+ set -- .xzy ..abc mikeserv home
+ set -- mno .xzy ..abc mikeserv home
+ set mno mno
+ set . mno mno
+ set .x/mno .xzy/mno
+ set .. .x/mno .xzy/mno
+ set ..a/.x/mno ..abc/.xzy/mno
+ set m/..a/.x/mno mikeserv/..abc/.xzy/mno
+ set h/m/..a/.x/mno home/mikeserv/..abc/.xzy/mno
+ p=~/h/m/..a/.x/mno
+ set home mikeserv
+ shift
+ p=~/m/..a/.x/mno
+ shift
+ p=~/..a/.x/mno
+
+ printf %s\n ~/..a/.x/mno
~/..a/.x/mno
+ set +f -xsmi
/f/b/.c/wizard_magic
ย่อแทน จุดมักพบเห็นได้ทั่วไปในสารบบโดยเฉพาะว่าเป็นเบาะแสเล็ก ๆ ที่คุณควรมอง