我需要運行一個readarray -d / -t用于將檔案路徑拆分為陣列的腳本,但readarray目標系統的不支持該-d選項(bash 版本 4.2.46)
由于我不知道 的確切行為readarray -d / -t,因此我很難為它撰寫解決方法。它不似乎可能的替代它IFS=/ read -a,因為包含控制字符的檔案名會打破它,如下所示:
IFS=/ read -a arr < <(echo /home/fravadona/$'\n'/underneath)
declare -p arr
# OUTPUT: declare -a arr='([0]="" [1]="home" [2]="fravadona")'
所以,我的第一個問題是,預期的結果是什么:
readarray -d / -t arr < <(echo /home/fravadona)
readarray -d / -t arr < <(echo /home/fravadona/)
readarray -d / -t arr < <(echo /home/fravadona/$'\n'/underneath)
最后,以下代碼readline -d / -t是否正確模擬?
filepath=/home/fravadona/$'\n'/underneath
unset arr; declare -a arr
prefix="${filepath%%/*}"
suffix="${filepath#*/}"
until [ "X$prefix" == "X$suffix" ]
do
arr =( "$prefix" )
prefix="${suffix%%/*}"
suffix="${suffix#*/}"
done
arr =( "$prefix" )
uj5u.com熱心網友回復:
希望這會達到您的預期:
filepath=/home/fravadona/$'\n'/underneath
IFS=/ read -d "" -r -a arr < <(printf "%s" "$filepath")
declare -p arr
uj5u.com熱心網友回復:
bash“readarray -d / -t”的確切行為是什么?
讀取所有輸入。拆分它/。洗掉/。分配給陣列。
什么是預期的結果:
以下腳本:
readarray -d / -t arr < <(echo /home/fravadona)
declare -p arr
readarray -d / -t arr < <(echo /home/fravadona/)
declare -p arr
readarray -d / -t arr < <(echo /home/fravadona/$'\n'/underneath)
declare -p arr
輸出:
declare -a arr=([0]="" [1]="home" [2]=$'fravadona\n')
declare -a arr=([0]="" [1]="home" [2]="fravadona" [3]=$'\n')
declare -a arr=([0]="" [1]="home" [2]="fravadona" [3]=$'\n' [4]=$'underneath\n')
以下代碼是否正確模擬了 readline -d / -t?
您的代碼不會從 stdin 讀取,因此它不會模擬readline. 您似乎假設輸入存盤在某個變數中。
以下代碼:
f() {
IFS= read -d '' -r filepath
arr=()
prefix="${filepath%%/*}"
suffix="${filepath#*/}"
until [ "X$prefix" == "X$suffix" ]
do
arr =( "$prefix" )
prefix="${suffix%%/*}"
suffix="${suffix#*/}"
done
arr =( "$prefix" )
}
f < <(echo /home/fravadona)
declare -p arr
f < <(echo /home/fravadona/)
declare -p arr
f < <(echo /home/fravadona/$'\n'/underneath)
declare -p arr
輸出:
declare -a arr=([0]="" [1]="home" [2]=$'fravadona\n')
declare -a arr=([0]="" [1]="home" [2]="fravadona" [3]=$'\n')
declare -a arr=([0]="" [1]="home" [2]="fravadona" [3]=$'\n' [4]=$'underneath\n')
所以它是一樣的,所以經過一些調整后的答案是肯定的。
奇怪的是你現在使用[ X技巧 - 舊的錯誤早已消失,無論如何==都是非標準的[......在bash中,只需使用[[ "$prefix" == "$suffix" ]]
相關:需要替代 readarray/mapfile 用于舊版本 Bash 上的腳本。我會使用零位元組,例如:
f() {
arr=();
while IFS= read -d '' -r elem || [[ -n "$elem" ]]; do
arr =("$elem")
done < <(
tr '/' '\0'
)
}
uj5u.com熱心網友回復:
[似乎] 不可能替換它,
IFS=/ read -a因為包含控制字符的檔案名會破壞它,
具體來說,包含換行符的檔案名會破壞它。其他控制字符應該不是問題。
所以,我的第一個問題是,預期的結果是什么:
readarray -d / -t arr < <(echo /home/fravadona) readarray -d / -t arr < <(echo /home/fravadona/) readarray -d / -t arr < <(echo /home/fravadona/$'\n'/underneath)
它們分別相當于
arr=('' home $'fravadona\n')
arr=('' home fravadona $'\n')
arr=('' home fravadona $'\n' $'underneath\n' )
請注意,每個陣列都有一個與第一個“行”相對應的空第一個元素,并洗掉了尾隨定界符。
并特別注意每個結果的最后一個元素都包含一個尾隨換行符。這是因為echo默認情況下以 1 結束其輸出,并且您指示readarray使用不同的行分隔符。
那么,您可能也對這些感興趣......
readarray -d / -t arr < <(echo -n /home/fravadona)
readarray -d / -t arr < <(echo -n /home/fravadona/)
readarray -d / -t arr < <(echo -n /home/fravadona/$'\n'/underneath)
...產生與...相同的結果
arr=('' home fravadona)
arr=('' home fravadona)
arr=('' home fravadona $'\n' underneath)
最后,以下代碼是否正確模擬了 readline -d / -t?
unset arr; declare -a arr prefix="${filepath%%/*}" suffix="${filepath#*/}" until [ "X$prefix" == "X$suffix" ] do arr =( "$prefix" ) prefix="${suffix%%/*}" suffix="${suffix#*/}" done arr =( "$prefix" )
不,它沒有,至少是因為條件[ "X$prefix" == "X$suffix" ]是錯誤的。例如,如果$filepath是,foo/foo則不會執行回圈的迭代,并且最終的值arr將只包含一個元素,而不是兩個。或者如果$filepath是/foo/bar/bar那么最終結果只有兩個元素,而不是三個。
這樣會更好:
unset arr
declare -a arr
case $filepath in
*/) suffix=$filepath;;
*) suffix=${filepath}/;;
esac
while [[ -n "$suffix" ]]; do
arr =(${suffix%%/*})
suffix=${suffix#*/}
done
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/333611.html
上一篇:在欄位值前添加字母
