bạn có thể làm điều đó như:
cd /usr///.//share/../share//man/man1 || exit
IFS=/; set -f
printf %.1s/ ${PWD%/*}
printf %s\\n "${PWD##*/}"
/u/s/m/man1
và đây là 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/
điều đó khá gần với việc thực hiện tất cả những thứ tương tự mà hàm thực hiện bên dưới. nó không viết tắt bằng dấu ngã hoặc chèn $PWD
vào đầu để không gạch chéo hàng đầu như chức năng thực hiện (và trên thực tế, không bao giờ in dấu gạch chéo hàng đầu) nhưng sau đó có thể được xử lý. nó xử lý các thành phần đường dẫn null, và các dấu chấm đơn và loại bỏ ..
các trường hợp.
đưa ra cùng một man
đường dẫn như cd
trên nó in:
u/s/m/man1
nó cũng sẽ in thêm một hoặc hai dấu chấm dẫn đầu cho mỗi thành phần đường dẫn bắt đầu bằng và không chỉ là một hoặc hai dấu chấm.
bạn đã hỏi về việc thực hiện nhiều hơn một ký tự cho một thành phần đường dẫn bắt đầu bằng a .
. Để làm điều đó, tôi nghĩ rằng mỗi thành phần sẽ cần sự chú ý riêng lẻ, và vì tôi tò mò, tôi đã cố gắng tìm ra một con đường chính tắc mà không cần thư mục thay đổi. sau một vài lần thử và sai, cuối cùng tôi đã quyết định cách duy nhất để làm đúng là làm điều đó hai lần - ngược và tiến:
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:--}"
}
để không bao giờ thay đổi thư mục hoặc cố gắng xác nhận sự tồn tại của bất kỳ thành phần đường dẫn nào, nhưng nó sẽ nén hoàn toàn các /
dấu phân cách lặp lại và loại bỏ /./
hoàn toàn các thành phần dấu chấm đơn và xử lý /../
các thành phần hai chấm một cách thích hợp.
khi $IFS
được đặt thành một số ký tự không phải khoảng trắng , một chuỗi gồm hai hoặc nhiều $IFS
ký tự sẽ dẫn đến một hoặc nhiều trường null. do đó, nhiều dấu gạch chéo liên tiếp có tác dụng với các đối số có giá trị null. điều tương tự cũng đúng với một $IFS
nhân vật hàng đầu . và vì vậy khi set -- $1
chia tách, nếu kết quả $1
là null thì nó bắt đầu bằng dấu gạch chéo, nếu không, ${1:+$PWD}
nếu không phải là null, thì tôi chèn $PWD
. nói cách khác, nếu đối số đầu tiên không bắt đầu bằng dấu gạch chéo, nó sẽ được $PWD
thêm vào trước. đó là gần như điều này để xác nhận đường dẫn .
mặt khác, for
vòng lặp đầu tiên đệ quy đảo ngược thứ tự của các thành phần đường dẫn, như:
1 2 3
1 2 3
2 1 3
3 2 1
... Trong khi làm như vậy, nó bỏ qua mọi thành phần dấu chấm đơn hoặc null và đối với ..
nó ...
1 .. 3
1 .. 3
3
3
... đường chuyền thứ hai đảo ngược hiệu ứng này và trong khi thực hiện, nó nén từng thành phần thành 2 chấm + char hoặc 1 chấm + char hoặc char .
vì vậy nó nên hoạt động theo một đường dẫn chính tắc bất kể sự tồn tại.
tôi đã thêm / bớt một chút vào vòng lặp thứ hai. bây giờ nó set
ít thường xuyên hơn (chỉ một lần cho mỗi [!./]*
thành phần) và case
hầu hết thời gian đánh giá mẫu ngắn mạch (nhờ vào mẫu đã nói ở trên) và bao gồm cả đánh giá so khớp cuộc gọi đuôi ~
. nếu tất cả hoặc một phần đầu (như được chia trên toàn bộ các thành phần) của đường dẫn chính tắc cuối cùng có thể khớp ~
, bit khớp sẽ bị loại bỏ và một chữ ~
sẽ được thay thế. để làm điều này, tôi đã phải duy trì một bản sao đầy đủ của đường dẫn bên cạnh chữ viết tắt (vì khớp với đường dẫn viết tắt ~
có lẽ sẽ không hữu ích lắm) , và vì vậy nó được giữ nguyên $3
. cuối cùngwhile
nhánh vòng lặp chỉ được chạy nếu ~
được khớp như một tập hợp con của $3
.
nếu bạn chạy nó với set -x
dấu vết được kích hoạt, bạn có thể xem nó hoạt động.
$ (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
. Dấu chấm thường rất phổ biến trong một thư mục cụ thể đến mức là một đầu mối rất nhỏ đến nơi bạn nên tìm kiếm.