无需知道路径即可大规模重命名随机命名的文件

时间:2016-04-26 09:34:25

标签: bash macos

在批量重命名路径中的文件时遇到问题。

这是我的问题: 我的驱动器大约有16000个或更多的文件(所有图像,但可能是.psd,.jpg,.ai,.png等)以非常混乱的方式散布在周围,但文件名幸运的是所有独特的,但是由于对于纯粹的数量,我无法肯定地说(我的意思是可能有2个文件名为abc.ai或等价,但不是很多)。我不知道路径,因为提供的csv只包含原始文件名,以及它们应该重命名为什么。

基本上,csv中的第一行是:

  

qwerty.jpg,asdfg.jpg

  

123-asd_qwe.ai,abcfgd.ai。

我确实尝试了几种解决方案; sed,一些脚本,我可以尝试的任何我真正做过的事。

我真的很想听到命题或想法,甚至是解决方案!

要注意:我试过::

sed 's/"//g' names.csv | while IFS=, read orig new; do echo mv "$orig" "$new"; done

sed 's/^/mv -i -v "/;s/, /" "/;s/$/";/' < names.csv | bash -

#!/bin/bash
 while read line          
 do          
      OldImageName=${line%,*}
      NewImageName=${line#*,}
      mv "$OldImageName" "$NewImageName"
 done <"names.csv"

3 个答案:

答案 0 :(得分:2)

如果您完全确定names.txtoldname,newname的顺序中具有名称的方式,则以下逻辑应该足够: -

#!/bin/bash

 while read line
 do
      # Splitting the line with delimiter as ',' and 
      # getting the fields before and after

      OldImageName=$(echo $line | cut -d "," -f 1) 
      NewImageName=$(echo $line | cut -d "," -f 2)

      if [ $(find . -name "$OldImageName" | wc -l) -gt 0 ]; then

          # Get the absolute path of the file

          path=$(dirname $(readlink -f "$OldImageName"))

          # Verbose option '-v' for verifying the file rename and 
          # to suppress errors if file not present

          mv -v "$path/$OldImageName" "$path/$NewImageName" 2>/dev/null 
      fi

 done <names.csv

答案 1 :(得分:1)

(在评论中澄清问题后重写了答案)。

只有当您的CSV包含整个路径而不仅仅是基本名称时,第一个解决方案才有效。您需要遍历它,找到每个文件并重命名。

sed -r 's/, ?/\t/' names.csv | while IFS=$'\t' read orig new; do 
   find $DIR -type f -name "$orig" | while read path; do
      dirname=`dirname "$path"`
      target_path="$dirname/$new"
      if [[ ! -f "$target_path"]]; then
         mv -v -- "$path" "$target_path"
      else 
         echo "Could not rename '$path' to '$target_path'. Target file exists" >&2 
      fi 
   done
done

$DIR替换为最顶层的目录。注意我假设每个基本名称可能与不同目录中的许多文件相对应。这就是我遍历find

输出的原因

答案 2 :(得分:0)

这是在上述特定情况下工作的完整解决方案 - 它需要考虑重复文件(在不同文件夹中),并且文件名(空格,重音等)的命名不会影响脚本。请参阅以下解决方案:

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

while read line
do
  OldImageName=$(echo $line | cut -d "," -f 1) 
  NewImageName=$(echo $line | cut -d "," -f 2)

  isMatchRelativePath=$(echo $(find . -name "$OldImageName"));
  isMatchNewName=$(echo $(find . -name "$NewImageName"));

  if [ ! -z "$isMatchRelativePath" ];
  then

      find . -name "$OldImageName" -print0 | while read -d $'\0' file
        do

        relativeFolder="${file%$OldImageName}"

        quote1="$relativeFolder$OldImageName";
        quote2="$relativeFolder$NewImageName";

        mv "${quote1}" "${quote2}"
        echo "$relativeFolder$OldImageName, $relativeFolder$NewImageName">>"$DIR/success.csv"
      done


  elif [ ! -z "$isMatchNewName" ]; then
       echo "alreadyRenamed"
      echo "$relativeFolder$OldImageName, $relativeFolder$NewImageName">>"$DIR/alreadyRenamed.csv"
  else
      echo "failed"
      echo "$relativeFolder$OldImageName, $relativeFolder$NewImageName">>"$DIR/failed.csv"
  fi

done <input.csv