从find命令输出中删除path

我有一个bash脚本,用于将代码从beta环境部署到生产环境,但是目前我必须将文件列表经常地添加到一个txt文件中,有时候我会错过一些。 基本上我的部署脚本猫/循环复制文件。 (出口/import分贝,以及这是不相关的..大声笑)

无论如何,我想使用find命令来生成过去14天内修改的文件列表。 问题是我需要删除path./为了使部署脚本工作。

以下是find命令用法的示例:

找 。 -type f -mtime -14> deploy.txt

下面是部署脚本中的deploy.txt部署deploy.txt行:

 for i in `cat deploy.txt`; do cp -i /home/user/beta/public_html/$i /home/user/public_html/$i; done 

任何想法如何使用bash脚本完成这个?

谢谢!

您可以使用带有%f-printf命令行选项来打印没有任何目录信息的文件名

 find . -type f -mtime -14 -printf '%f\n' > deploy.txt 

或者你可以使用sed来删除./

 find . -type f -mtime -14 | sed 's|./||' >deploy.txt 

./应该是无害的。 大多数程序将把/foo/bar/foo/./bar视为等效。 我意识到这看起来不是很好,但根据你发布的内容,我没有看到为什么它会导致你的脚本失败。

如果你真的想剥离它, sed可能是最干净的方式:

 find . -type d -mtime 14 | sed -e 's,^\./,,' > deploy.txt 

如果你使用的是GNU find(例如大多数Linux系统)的系统,你可以用find -printf

 find . -type d -mtime 14 -printf "%P\n" > deploy.txt 

%P返回find的每个文件的完整path,减去命令行中指定的path,直到并包括第一个斜杠。 这将保留你的目录结构中的任何子目录。

为什么你需要./ ? 在一条道路上是有效的。 所以

 cp -i dir1/./somefile dir2/./somefile 

只是好!

但是,如果您想在find中删除目录名称您可以使用%P arg到-printf

男人发现(1)说:

  %P File's name with the name of the command line argument under which it was found removed. 

一个例子

 $ find other -maxdepth 1 other other/CVS other/bin other/lib other/doc other/gdbinit $ find other -maxdepth 1 -printf "%P\n" CVS bin lib doc gdbinit 

注意第一个空行! 如果你想避免使用-mindepth 1

 $ find other -mindepth 1 -maxdepth 1 -printf "%P\n" CVS bin lib doc gdbinit 

find -printf解决scheme在FreeBSD上不起作用,因为find没有这个选项。 在这种情况下,AWK可以提供帮助。 它返回一个姓氏($ NF),所以它可以在任何深度工作。

 find /usr/local/etc/rc.d -type f | awk -F/ '{print $NF}' 

PS:取自D.Tansley的“Linux和Unix shell编程”一书

那么你有几个select。 你可以在find中使用-printf选项来打印出文件名,或者你可以使用像sed这样的工具来简单地./

 # simply print out the filename, will break if you have sub-directories. find . -mtime -14 -printf '%f\n' # strip a leading ./ find . -mtime -14 | sed -e 's/^\.\///' 

sed是完美的这种事情。

 $ find . -type f -mtime -14 find . | sed 's/^\.\///' > deploy.txt 

一个快速的解决scheme,如果我正确地理解了这个问题,使用cut命令的输出:

 $> find . -type f -mtime -14 | cut -b 3- > deploy.txt 

这将剥离第一个字符从结果的每一行(在你的情况下./ )。 可能不是最好的解决scheme,但适用于你的情况。

我不知道我们在谈论什么types的文件名,但是有空格或换行符的东西会把大多数解决scheme置于危险之中。

我的build议是使用shell的参数扩展去除每个文件名中的字符:

 find . -mtime -14 -exec sh -c 'printf "${0#./}\n"' {} \; >deploy.txt 

如果你真的喜欢pipe道,你可以使用一个“安全的”分隔符,如null,用xargs来接收每个文件名:

 find . -mtime -14 -print0 | xargs -0 -n 1 sh -c 'printf "${0#./}\n"' >deploy.txt 

请记住,这个输出不是空分隔的,所以虽然它可能足以进行眼球检查,但是这些解决scheme都不会生成一个可以安全用于自动化的deploy.txt文件,除非您对源代码非常有信心文件名。