我试图通过使用文件扩展名(不完美但足以满足我的需要)从运行脚本的目录中递归地自动化某些文件(流行的图像和视频格式)的散列。
我对bash没什么经验,也无法弄清楚为什么这个循环没有按预期运行,尽管我怀疑是F_EXTENSION
变量和|
到tr
命令的分配。它将散列目录中的所有文件,无论其扩展名如何。我显然做错了什么。
为清晰起见,以下只是代码的一小部分,在其他地方分配了更多变量(例如下面引用的文件名)。
FILES=$( find ./* -type f )
EXTENSIONS=(.jpg .gif .png .bmp .avi .mpg .mov .mkv .flv .wmv .mp4)
SAVEIFS=$IFS
IFS=$'\n'
for FILE in $FILES; do
F_EXTENSION=${FILE: -4} | tr '[:upper:]' '[:lower:]'
if [[ "${EXTENSIONS[@]}" =~ "${F_EXTENSION}" ]]; then
HASH=$( md5sum $FILE )
echo ${HASH} | cut -c1-32 >> ${TEMPFILE}
else
echo "Skipping ${FILE}" >> ${LOGFILE}
fi
done
IFS=$SAVEIFS
在尝试各种方法之后,我不得不承认它有一双新鲜的眼睛。有什么想法吗?
答案 0 :(得分:2)
您的问题是关于
Fruits
Juices
Drinks
createIndexCB: Drinks
createIndexCB: Drinks
createIndexCB: Drinks
这在很多方面都是错误的。它的作用如下:
在子shell中执行命令
F_EXTENSION=${FILE: -4} | tr '[:upper:]' '[:lower:]'
,然后将其标准输出传递给命令F_EXTENSION=${FILE: -4}
。
这是错误的,因为你当然不希望在子shell中执行赋值tr '[:upper:]' '[:lower:]'
(因为子shell退出后,子shell中的所有赋值都会被遗忘)。此外,此赋值不会向标准输出输出任何内容,因此F_EXTENSION=${FILE: -4}
永远不会读取任何内容。
我知道您要执行以下操作:在所有具有数组tr
中给出的扩展名并且在当前目录中找到(递归)的文件中,计算其md5sum,将此md5sum附加到文件EXTENSIONS
;在没有此扩展名的所有文件中,输出您正在跳过该文件。
这是实现这一目标的可能性:
${TEMPFILE}
使用Bash≥4会有其他可能性,但你仍然坚持使用Bash 3.2 ......
由于我们使用的是globs,因此我们不需要使用# Don't use an array to store the extensions, use a glob.
# We'll export it as it will be used in a child process (spawned by find)
# We'll also export the variables tempfile and logfile for the same reason
# To export them all automatically, we use set -a
set -a
extensions_glob=+(jpg|gif|png|bmp|avi|mpg|mov|mkv|flv|wmv|mp4)
tempfile=/path/to/tempfile
logfile=/path/to/logfile
set +a
find ./ -type f -exec bash -c -O nocasematch '
if [[ $1 = *.$extensions_glob ]]; then
md5sum < "$1" | cut -d" " -f1 >> "$tempfile"
else
echo "Skipping $1" >> "$logfile"
fi
' bash {} \;
来强制使用小写:我们使用shell选项tr
代替!
答案 1 :(得分:1)
您打算捕获命令的输出吗?
F_EXTENSION="$(echo ${FILE: -4} | tr '[:upper:]' '[:lower:]')"
现在您有效地将${FILE: -4}
分配给F_EXTENSION
,然后将任何内容回送到tr
。您需要使用反引号或${}
来捕获stdout
,同时将扩展名回显到tr
。
如果您想要一种更可靠的方式来获取扩展程序而不依赖于其长度,this提供此解决方案:
filename=$(basename "$fullfile")
extension="${filename##*.}"
filename="${filename%.*}"