与通配符进行文件名比较

时间:2016-04-15 13:15:32

标签: macos bash shell

我正在编写一个脚本,我需要将文件名与另一个文件名进行比较,并查找特定的更改(在这种情况下,当"(x)"在OS X需要添加时添加到文件名中一个文件到一个目录,当一个文件名已经存在时)所以这是一个脚本的摘录,修改为在没有其余部分的情况下进行测试。

#!/bin/bash

p2_s2="/Path/to file (name)/containing - many.special chars.docx.gdoc"
next_line="/Path/to file (name)/containing - many.special chars.docx (1).gdoc"
file_ext=$(echo "${p2_s2}" | rev | cut -d '.' -f 1 | rev)
file_name=$(basename "${p2_s2}" ".${file_ext}")
file_dir=$(dirname "${p2_s2}")

esc_file_name=$(printf '%q' "${file_name}")
esc_file_dir=$(printf '%q' "${file_dir}")
esc_next_line=$(printf '%q' "${next_line}")

if [[ ${esc_next_line} =~ ${esc_file_dir}/${esc_file_name}\ \(?\).${file_ext} ]]
 then
  echo "It's a duplicate!"
fi

我在这里尝试做的是检测文件next_line是否与p2_s2重复。由于我期待多个重复,next_line可以在文件名末尾添加(1)或括号中的任何其他数字(虽然我确定没有两位数)。因为我不能用中间的通配符做一个简单的字符串,我尝试使用" =〜"操作员并逃避所有特殊字符。知道我做错了吗?

2 个答案:

答案 0 :(得分:1)

您可以修剪ps2_s2的扩展程序,修剪next_line的扩展名,包括括号内的数字,看看你是否得到相同的内容文件名。如果你这样做 - 它是重复的。为此,[[允许我们在字符串和Glob之间进行比较。

我使用了extglob+( ... )模式,因此我可以使用+([0-9])来匹配括号内的数字。请注意, extglob shopt -s extglob启用。

#!/bin/bash

p2_s2="/Path/to/ps2.docx.gdoc"
next_line="/Path/to/ps2(1).docx.gdoc"

shopt -s extglob
if [[ "${p2_s2%%.*}" = "${next_line%%\(+([0-9])\).*}" ]]; then
    printf '%s is a duplicate of %s\n' "$next_line" "$p2_s2"
fi

编辑:

我现在看到你已经编辑了你的问题,所以如果这个解决方案还不够,我肯定它会成为一个很好的模板。

答案 1 :(得分:0)

(1)中的next_line未在原始文件名中的第二个到最终.之前的最终.之前出现但您只剥离了一个.作为扩展名。

因此,当您生成比较文件名时,最终会得到/Path/to\ file\ \(name\)/containing\ -\ many.special\ chars.docx\ \(?\).gdoc,这与您的预期不符。

如果您已将set -x添加到脚本顶部,则您已经看到了shell实际执行的操作并看到了这一点。

OS X在这种情况下实际上做了什么?它是否在(#)之前添加.gdoc? Does it add it before。docx`?是否取决于OS X 是否知道文件名是什么(它可以是本机打开的某种类型)?