我有最初包含不同目錄路徑的字串,其中第二個和第二個最后一個子目錄的長度可以不同,就像這樣
/home/Leo/Work/CMI/ARCH/MWS/Disks
/home/Cleo/Work/CMI/ARCH/BK/Disks
我想修剪前 5 個子目錄,只顯示最后 2 個,就像這樣
echo "/MWS/Disks"
echo "/BK/Disks"
從初始字串中修剪前 5 個子目錄的一種方法可能是左移每個字符,直到兩個字串都以倒數第二個“/”開頭。
的擊初學者指南描述了一種shift built-in在一個命令,左移位位置引數和扔掉未使用的引數。但是,這是否可以用于從上述字串中修剪前 5 個子目錄并不是很明顯。
在 Bash 中,如何減少這些字串,最好不使用回圈?
澄清
從評論來看,需要更多的背景關系。我的 Bash 腳本從 8 英寸軟盤映像恢復歷史 Mdos 和 Qdos 檔案,并將檔案保存到硬碟驅動器上的目錄中。
無論好壞,我創建了一個定制方案,該方案使用 3 個字符的變數名稱存盤目錄路徑,其中每個名稱都是當前目錄路徑部分的首字母縮寫詞。
例如MWC是$MY/Work/CMI以下路徑中的首字母縮寫詞
MY="$USER"
MWC="C:/cygwin64/home/$MY/Work/CMI"
cd "$MWC"
pwd
C:/cygwin64/home/$MY/Work/CMI
類似地,3 個字符的變數指向樹的下一個子目錄
WCA="$MWC/ARCH"
即C:/cygwin64/home/$MY/Work/CMI/ARCH,通往檔案所有者畫廊的路徑。
隨著目錄路徑加長,3 個字符的變數通過在串列中保留空白來輕松識別路徑。然而,只要我的腳本參考路徑,就會出現完整路徑。因此需要修剪最終用戶不感興趣的字串部分。
uj5u.com熱心網友回復:
如果子目錄的個數一直都一樣,可以使用引數擴展去掉前5個子目錄:
s=/home/Leo/Work/CMI/ARCH/MWS/Disks
s=/${s#/*/*/*/*/*/}
echo $s # /MWS/Disks
或者,如果您知道無論路徑的深度如何,您都需要最后兩部分:
s=/home/Leo/Work/CMI/ARCH/MWS/Disks
last=/${s##*/}
last_but1=${s%$last}
last_but1=/${last_but1##*/}
echo $last_but1$last # /MWS/Disks
${s#PATTERN}從$s.${s%PATTERN}洗掉 PATTERN 的開頭$s。- 使用
#或%,找到 PATTERN 的最短匹配。將它們加倍可以使匹配時間盡可能長。
uj5u.com熱心網友回復:
作為引數擴展的替代方法,您可以使用=~運算子:
dir='/home/Leo/Work/CMI/ARCH/MWS/Disks'
[[ $dir =~ /[^/]*/[^/]*$ ]] && echo "${BASH_REMATCH[0]}"
uj5u.com熱心網友回復:
假設輸入來自檔案(或從另一個作業系統行程流式傳輸/管道傳輸)......
樣本輸入:
$ cat dir.file
/home/Leo/Work/CMI/ARCH/MWS/Disks
/home/Cleo/Work/CMI/ARCH/BK/Disks
一個awk想法:
awk 'BEGIN {FS=OFS="/"} {print OFS $(NF-1),$(NF)}' dir.file
這會產生:
/MWS/Disks
/BK/Disks
如果需要存盤結果以供以后使用,則根據需要添加一些代碼應該不會太難(例如,重定向到檔案、管道到另一個行程、作為輸入傳遞給while/read回圈、加載到陣列等) .
如果 OP 一次處理這些字串(例如,作為回圈中的變數),我可能會堅持使用引數替換解決方案(請參閱 choroba 的答案),它不需要任何開銷來生成子行程。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/351551.html
下一篇:什么是C中的繁忙回圈?
