我有一个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文件,除非您对源代码非常有信心文件名。