从 find 命令输出中删除路径

Mik*_*980 38 bash find

我有一个 bash 脚本,用于将代码从 beta 环境部署到生产环境,但目前我必须手动将文件列表添加到 txt 文件中,有时我会错过一些。基本上我的部署脚本 cat/loops 复制文件。(导出/导入数据库也是如此,但这无关紧要..lol)

无论如何,我想使用该find命令生成过去 14 天内修改的文件列表。问题是我需要删除路径./才能使部署脚本正常工作。

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

找 。-type f -mtime -14 > 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
Run Code Online (Sandbox Code Playgroud)

知道如何使用 bash 脚本来实现这一点吗?

谢谢!

use*_*517 41

您可以使用-printf命令行选项 with%f仅打印文件名,而无需任何目录信息

find . -type f -mtime -14 -printf '%f\n' > deploy.txt
Run Code Online (Sandbox Code Playgroud)

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

find . -type f -mtime -14 | sed 's|^./||' >deploy.txt
Run Code Online (Sandbox Code Playgroud)

  • 使用 `%P` 代替 `%f`。这只是切断了命令行中给出的路径。 (17认同)
  • 当您使用 `|` 作为分隔符时不会。 (6认同)
  • 使用 `%f` 将删除所有目录,而不仅仅是 `./`。如果 find 返回的任何文件位于子目录中,这将破坏他的部署脚本。 (4认同)
  • 这似乎是一个不错的技巧,但仅适用于 Linux。常规的“find(1)”——例如在 FreeBSD 上找到的,没有“-printf”谓词... (3认同)
  • @Iain 你确实需要转义 `.`。也许最好使用行首锚点:`s|^\./||` (2认同)

Jam*_*ger 13

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

如果你真的想脱掉它,sed可能是最干净的方法:

find . -type d -mtime 14 | sed -e 's,^\./,,' > deploy.txt
Run Code Online (Sandbox Code Playgroud)

如果您使用的是带有 GNU find 的系统(例如大多数 Linux 系统),您可以使用以下命令一次性完成find -printf

find . -type d -mtime 14 -printf "%P\n" > deploy.txt
Run Code Online (Sandbox Code Playgroud)

%P返回每个文件的完整路径发现,减去在命令行上指定的路径,直至并包括第一个斜杠。这将保留目录结构中的所有子目录。


Tru*_*ueY 7

为什么需要脱掉./?在路径中具有是有效的。所以

cp -i dir1/./somefile dir2/./somefile
Run Code Online (Sandbox Code Playgroud)

没关系!

但是,如果您想在 find 中删除目录名称,则可以使用%Parg to -printf.

man find(1)说:

         %P     File's name with the name of the  command  line  argument
                 under which it was found removed.
Run Code Online (Sandbox Code Playgroud)

一个例子

$ 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
Run Code Online (Sandbox Code Playgroud)

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

$ find other -mindepth 1 -maxdepth 1 -printf "%P\n"
CVS
bin
lib
doc
gdbinit
Run Code Online (Sandbox Code Playgroud)


小智 6

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

find /usr/local/etc/rc.d -type f | awk -F/ '{print $NF}'
Run Code Online (Sandbox Code Playgroud)

PS:摘自 D.Tansley 《Linux 和 Unix shell 编程》一书