【问题标题】:swap filenames when their substring match当子字符串匹配时交换文件名
【发布时间】:2015-03-24 15:53:02
【问题描述】:

folder1 中有 1000 多张图片,文件名为 “Firstname_Lastname_0032somenumber.jpg”。我必须用 folder2 中的 200 多张更新图像替换其中一些图像,文件名为 "firstname lastname.jpg"

所以我正在尝试编写一个 bash 脚本来执行此操作,但我无法完成

  1. 将文件名存储到 2 个数组 (arr1, arr2)

     shopt -s nullglob 
     arr1=(folder1/*)
     arr2=(folder2/*)
    
  2. 获取arr1中每个元素的文件名(名字/姓氏)的子字符串

    for i in "${arr1[@]}"
     do
       echo "$i" | cut -d'/' -f 2 | cut -d'_' -f 1 |  tr '[:upper:]' '[:lower:]'
    done
    
  3. 检查子串是否与arr2中的子串匹配

  4. 重命名文件

【问题讨论】:

  • 请不要忘记对任何提供有用信息的答案进行投票,并(正式地)“接受”答案以表明您使用哪一个来解决您的问题。这就是 StackOverflow.com 网站的工作方式,以最大限度地帮助最多人数。

标签: bash shell


【解决方案1】:

更好的解决方案是关联数组。第一步就像您在第 2 步中的代码创建一个数组,其中来自 folder1 的文件名是键:

declare -A map
for i in "${arr1[@]}"; do
   key=$(basename "$i" | cut -d'_' -f 1-2 |  tr '[:upper:]' '[:lower:]' | tr '_' ' ')
   map[$key]="$i"
done

这会将Firstname_Lastname_0032somenumber.jpg 转换为firstname lastname(全部小写,_ 替换为空格)。

现在您遍历文件夹 2 中的文件,以类似的方式处理它们以获取获取新文件名的密钥:

for i in "${arr2[@]}"; do
   key=$(basename "$i" .jpg | tr '[:upper:]' '[:lower:]')
   newName=${aa[$key]}
   if [[ -n "$newName" ]]; then
       echo "mv \"$folder2/$i\" \"$folder1/$newName\""
   fi
done

相关:

【讨论】:

  • 这种方法的问题在于它不能很好地扩展,因为您将目录中的所有文件(可能是 zetabytes 时代的任何大小)都缓存在内存中。
  • OP 说“1000+”个文件。但是 BASH 无论如何都会这样做,因为它没有 API 来遍历目录中的条目($folder1/* 扩展为所有文件的列表,因此 BASH 将它们全部保存在内存中)。最后,大多数文件系统都很慢,单个文件夹中有大量文件,这通常无关紧要:-)
【解决方案2】:

我的方法可能更像是一次从 folder1 循环读取文件,从文件中剥离路径的前导部分(您可以使用 basename 和 dirname 命令拆分路径组件),然后将文件名拆分为标记,重新组合标记并将它们复制到文件夹 2,方法是将固定的文件名附加到该字符串。

for path in $(ls "folder1/"*); do {
  file=$(/usr/bin/basename path)
  firstAndLast=${file%_*}
  first=${firstAndLast%%_*}
  last=${firstAndLast##*_}
  outputPath=folder2/${first}${last}.jpg
}

当然,您也可以翻译字符串的字母大小写,这与您所做的类似。您应该能够在 *NIX 系统中的 /usr/bin 或 /bin 中找到 basename 和 dirname。

【讨论】:

  • $(folder1/*) 将尝试执行文件夹中的第一个文件并将所有其他文件作为参数传递给它。你的意思可能是"$folder1/"*
  • @AaronDigulla 实际上,我的意思是$(ls folder1/*),我会在我的例子中更正它
  • 这在这种情况下有效,但当folder1 包含名称中带有空格的文件时,它会变得很脆弱。
  • @AaronDigulla - 好点子。您的第一个建议可能是正确的,而 ls 是多余的。我会再次编辑它。
猜你喜欢
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 2021-03-11
  • 2015-04-04
  • 1970-01-01
  • 2019-12-05
  • 2020-03-25
相关资源
最近更新 更多