使用list-Bash Script / Unix重命名文件夹和子文件夹中的文件

时间:2014-12-29 15:35:25

标签: bash unix

我试图重命名文件夹中包含的文件&子文件夹。我在每个文件夹下包含各种文件的许多子文件夹,所以我的目标是在顶级文件夹中运行一个脚本,希望扫描整个子文件夹数组,并将旧文件名重命名为新文件名。一个单独的文本文件。

例如:

Abc075.tif ---------- Xyz.tif

def958.pdf ---------- pqr.pdf

我的这个bash脚本适用于文件夹级别,如果我将其复制到每个文件夹(和子文件夹),然后从那里运行。

#!/bin/bash
while read -r old new
do
    arr=( ${old} )
    if (( ${#arr[@]} == 1 ))
    then
        mv "${arr[0]}" "$new"
    else
        echo "Error: Multiple files found for $old: ${arr[@]}"
    fi    
done < replace.txt

抱歉,我的知识有限,但我已尝试将其修改为;

#!/bin/bash
find -type f -iname '*.*' -print0 | while read -r old new
do
    arr=( ${old} )
    if (( ${#arr[@]} == 1 ))
    then
        mv "${arr[0]}" "$new"
    else
        echo "Error: Multiple files found for $old: ${arr[@]}"
    fi    
done < replace.txt

这会执行但不会奏效。我还使用这个find命令尝试了第一个脚本;

find /path -type f -name "*.*" -exec /path_of_script.sh {} +

非常感谢提前。

1 个答案:

答案 0 :(得分:3)

要使用批处理mv命令,您需要创建一个制表符分隔文件,该文件将明确添加您的replace.txt未命中的目录结构,如下所示:

full/path/old.stuff<TAB>full/path/new.stuff

为了达到这个目的,你必须:

  1. 列出文件及其路径
  2. 提取基本名称(但保留指向路径信息的链接)
  3. 将basenames与您的replace.txt文件匹配以获取新名称
  4. 重新创建新的完整路径
  5. 然后执行mv命令。
  6. 因此我们需要使用大表格和findbasenamejoin等工具进行一些步骤(后者还需要进行一些排序)

    1)转到必须进行更改的最上面的目录,然后从:

    开始
    find . > all_paths.ls
    

    然后我们得到类似于你在replace.txt中的基本名称:

    for path in `cat all_paths.ls` ; do basename $path ; done > all_names.ls
    

    我们还需要dirnames:

    for path in `cat all_paths.ls` ; do dirname $path ; done > all_dirs.ls
    

    2)这两个将创建一个有用的表(组合名称以匹配您的replace.txt文件,同时仍然跟踪dirs):

    paste all_names.ls all_dirs.ls > all_name-dir.tsv
    

    3)由于join的魔力,我们现在使用你的replace.txt文件:

    sort replace.txt > replace.sorted.txt
    sort all_name-dir.tsv > all_name-dir.sorted.tsv
    # join will work fine because "old basenames" are in the first column of both tables
    join -t "<TAB>" all_name-dir.sorted.tsv replace.sorted.txt > todo_name-dir-newname.tsv
    

    <TAB>代表真正的制表符(您可以使用CTRL + V然后选择TAB键在shell中输入)

    结果应该有三列,内容如下:

    old.stuff<TAB>full/path/<TAB>new.stuff
    

    4)为了能够通过move命令使用所有这些,我们只需稍微重新塑造这个并将路径粘合在一起(放一些&#34; /&#34;返回)

    # get the columns back
    cut -f2 < todo_name-dir-newname.tsv > todo_dirs.ls
    cut -f1 < todo_name-dir-newname.tsv > todo_oldnames.ls
    cut -f3 < todo_name-dir-newname.tsv > todo_newnames.ls
    
    # glue 2 and 1 together for reconstructed old paths
    paste todo_dirs.ls todo_oldnames.ls | tr "\t" "/" > todo_oldpaths.ls
    
    # same for the new ones
    paste todo_dirs.ls todo_newnames.ls | tr "\t" "/" > todo_newpaths.ls
    
    # and we get the table we wanted
    paste todo_oldpaths.ls todo_newpaths.ls > replace_table.tsv
    

    5)现在终于你可以继续前进:

    for line in `cat replace_table.tsv`
     do oldpath=`echo $line | cut -f1`
        newpath=`echo $line | cut -f2`
        mv $oldpath $newpath
     done