我如何编写一个可以搜索,重命名和替换文件的bash脚本

时间:2015-04-14 08:25:51

标签: bash shell

我在源文件夹中有一大堆文件需要更新到目标文件夹。源文件夹中的布局是扁平的,没有子目录,如:

src\a.h
   \a.c
   \b.h
   \b.c
   \c.h
   \c.c

目标文件夹包含多个深层子目录,例如:

dst\App\a.h
   \App\a.c
   \USBD\CDC\b.h
   \USBD\CDC\b.c
   \USBH\CORE\FUNCTION\c.h
   \USBH\CORE\FUNCTION\c.h

我需要搜索" dst"中的所有文件。递归目录,如果它们中的任何一个匹配" src"中的任何文件。目录,然后重命名" dst"作为XX.sav(XX是原始名称)并复制来自" dst"到" src"。

感谢

2 个答案:

答案 0 :(得分:2)

假设您确实要从src复制到dstsrcdst是兄弟姐妹,并且该命令是从公共父目录运行的,尝试:

find dst -type f -exec sh -c 'test -f src/${0##*/} && 
    { mv $0 $0.sav && cp src/${0##*/} $0; }' {} \;

如果最后两个假设不正确,请尝试(未经测试):

find /path/to/dst -type f -exec sh -c 'test -f $1/${0##*/} && 
    { mv $0 $0.sav && cp $1/${0##*/} $0; }' {} /path/to/src \;

您应该小心:如果.sav中存在任何现有dst个文件,则可能会被覆盖,如果.sav中有src个文件,您可能会被风dst中的.sav.sav个文件与此命令本身正在创建的相关.sav文件的副本相同。如果相关,请使用mv -i来解决这些问题。如果现有文件的数量很多,mv -i可能不是合适的解决方案。

答案 1 :(得分:0)

找到问题的解决方案有几个步骤。

首先,您需要遍历src文件夹中的所有文件,以确保您知道在dst中要查找的内容。这可以在bash中轻松完成:

for filename in src/*
do
    echo "$filename" # simple sanity check
done

既然您知道自己在寻找什么,就可以使用命令find来尝试查找dst中的文件。由于此命令本身启用了递归查找,因此您无需执行任何特殊操作。但是,您可能希望查找文件的名称,而不是包含目录结构的整个路径。这样的事情应该有效。

for filename in src/*
do
    pattern=$(basename $filename) # remove folder from filename
    for another_filename in $(find dst -name "$pattern")
    do
        echo "$filename -> $another_filename" # another sanity check
    done
done

既然您有src的文件与dst中的文件匹配,您只需使用cpmv即可获得所需内容。

这远不是最短的解决方案,但是一旦你找到了你需要的命令,就应该很容易理解和改进。