带TR的字符串数组中的字符串操作

时间:2016-06-18 15:02:44

标签: bash

我试图通过使用文件扩展名(不完美但足以满足我的需要)从运行脚本的目录中递归地自动化某些文件(流行的图像和视频格式)的散列。

我对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

在尝试各种方法之后,我不得不承认它有一双新鲜的眼睛。有什么想法吗?

2 个答案:

答案 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%.*}"