我正在尝试将文件名放在一个只包含一个文件的文件夹中。
仅供参考:$FOLDER_TMP
包含空格,这就是我使用printf
function nameofkeyfile(){
FOLDER_TMP="${PWD%/*/*}/folder/"
FOLDER=$(printf %q "${FOLDER_TMP}")
FILENAME=ls "$FOLDER" # Error: No such file or directory
# or this: FILENAME=$(ls "$FOLDER") # Error: No such file or directory
FNAME=`basename $FILENAME`
}
问题在于: FILENAME = ls" $ FOLDER" #错误:没有这样的文件或目录
你知道为什么 - 是的文件夹在那里?
如果我回复$FOLDER
它给了我正确的文件夹。
答案 0 :(得分:2)
要将输出ls "$FOLDER"
存储在变量中,请将其放在子shell中:
FILENAME=$(ls "$FOLDER")
另一个问题是printf
。
它在字符串中添加了转义的反斜杠,
当您尝试在下一步中列出目录时,
这些反斜杠在字面上由shell使用。
请放弃printf
:
function nameofkeyfile() {
FOLDER="${PWD%/*/*}/folder/"
FILENAME=$(ls "$FOLDER")
FNAME=$(basename $FILENAME)
}
最后,使用$(...)
比使用`...`
更好:
答案 1 :(得分:2)
我正在尝试将文件名放在一个只包含一个文件的文件夹中。
你肯定有错误的方法。
相反,请考虑像这样使用globbing:
作业
fname=( "${PWD%/*/*}"/folder/* )
将填充数组 fname
将扩展给定的glob:即目录"${PWD%/*/*}"/folder/
中的所有文件(如果有)。如果根本没有文件,那么你的数组将包含glob,逐字。
因此,更强大的方法如下:
nameofkeyfile() {
fname=( "${PWD%/*/*}"/folder/* )
# Now check that there's at most one element in the array
if (( ${#fname[@]} > 1 )); then
echo "Oh no, there are too many files in your folder"
return 1
fi
# Now check that there is a file
if [[ ! -f ${fname[0]} ]]; then
echo "Oh no, there are no files in your folder"
return 1
fi
# Here, all is good!
echo "Your file is: $fname"
}
这使用Bash(命名)数组。如果您希望该函数符合POSIX,那么它非常简单,因为POSIX shell有一个未命名的数组(位置参数):
# POSIX-compliant version
nameofkeyfile() {
set -- "${PWD%/*/*}"/folder/*
# Now check that there's at most one element in the array
if [ "$#" -gt 1 ]; then
echo "Oh no, there are too many files in your folder"
return 1
fi
# Now check that there is a file
if [ ! -f "$1" ]; then
echo "Oh no, there are no files in your folder"
return 1
fi
# Here, all is good!
echo "Your file is: $1, I'll store it in variable fname for you"
fname=$1
}
我没有从文件名中删除完整路径,但这非常简单(不要使用basename
!): 1
fname=${fname##*/}
更确切地说:在Bash版本中,您可以使用:
fname=${fname[0]##*/}
在POSIX版本中您使用:
fname=${1##*/}
1 使用参数扩展来获取基本名称时有一个问题,它是/
的情况。但似乎你不会遇到这种情况,所以这一切都很安全!