【问题标题】:Using find and exec inside while loop在 while 循环中使用 find 和 exec
【发布时间】:2019-02-19 17:06:10
【问题描述】:

我有一个 .txt 文件,其中包含各种文件的名称。

当我简单地使用 while 循环时,它可以正常工作,

while read -r name
do
  echo "$name"
done <fileNames.txt

但是, 当我尝试在循环中使用 find 时,如下所示:

while read -r name
do
  find ./ -iname "$name" -exec sed -i '1s/^/NEW LINE INSERTED \n/' '{}' ';'
done < fileNames.txt

什么都没有发生!

如果我在循环外使用 find 与特定文件名一样,它会执行它应该做的事情,我也可以在具有特定文件类型的所有文件上使用它,但它在循环内不起作用。

我在这里做错了什么?

我正在尝试从文件中读取文件名,递归地在文件夹中搜索它,然后使用 sed 在开头附加一行。

【问题讨论】:

  • 你还需要find -exec吗?为什么不能直接使用sed?名称是否因大小写而异?还是它们在目录树中的某个地方?
  • @BenjaminW。是的,文件位于树中的不同位置。
  • fileNames.txt 是否使用 DOS 行尾?
  • 另外,仅仅因为您可以回显$name 的值并不一定意味着当前目录中有一个具有该名称的文件。
  • @CharlesDuffy 在包含 xtrace 时获得正确的输出,我认为 dos2unix unix 有所帮助。这次我使用命令进行了转换,之前我只是在notepad++中尝试。感谢您的帮助。

标签: bash sed git-bash


【解决方案1】:

使用 xargs 代替捕获 find 的结果

while read -r name
do
  find ./ -iname "$name" |xargs sed -i '1s/^/NEW LINE INSERTED \n/'
done <fileNames.txt

【讨论】:

  • 这实际上并不能解决任何问题,但它引入了一个巨大的安全漏洞。如果有人创建了一个带有$'\n/etc/passwd\n' 作为其名称子集的文件,则此xargs 命令将告诉sed 修改/etc/passwd。 OP 代码使用的find ... -exec 方法更安全。
  • 查看the Actions in Bulk section of UsingFind 中关于xargsBashPitfalls #56 的警告。
  • 我想说,安全始终是一个问题。
  • @KyleBanerjee, ...该网站的重点是成为教学资源。如果我们正在教授的实践只有在您从未对上传/接收/第 3 方提供的文件进行操作时才安全,那么在旁边提供警告是合理的(如果该实践有足够的价值值得在all) -- 否则,人们怎么知道他们正在阅读的做法是危险的?
  • @AamirYousuf 您可以认为您知道某物是什么或包含什么,但优雅地处理期望与现实不同的情况至关重要。我遇到的最糟糕的数据丢失事件是在一个脚本中运行的文件“永远不可能”具有不仅仅是 20 个十六进制字符的名称 - 直到一个新程序使用的 C 库中的一个错误生成这些文件将随机垃圾从内存转储到用于文件名的缓冲区中。纯错误,没有恶意,但该缓冲区包含一个由空格包围的 *,结果是丢失了 TB 的备份。
猜你喜欢
  • 2013-11-08
  • 1970-01-01
  • 2016-11-09
  • 2021-07-18
  • 2020-05-27
  • 2013-08-27
  • 2016-03-18
  • 2016-11-27
  • 1970-01-01
相关资源
最近更新 更多