1

这是针对苹果平台的。我的最终目标是查找并替换 firefox 首选项文件“prefs.js”中的一行以关闭更新。我希望能够为 Mac 上的所有帐户执行此操作,包括用户模板(示例中未包含该模板)。到目前为止,我已经能够获得包含 prefs.js 文件的所有路径的列表:

find /Users -name prefs.js

然后我将旧偏好和新偏好放入变量中:

oldPref='user_pref("app.update.enabled", false);'
newPref='user_pref("app.update.enabled", true);'

然后我有一个带有 sed 命令的“for 循环”,用新的首选项替换旧的首选项:

for prefs in `find /Users -name prefs.js`
  do
  sed "s/$oldPref/$newPref/g" "$prefs"
done

我遇到的问题是“查找”命令返回完整路径,路径名中带有愚蠢的“应用程序支持”,如下所示:

/Users/admin/Library/Application Support/Firefox/Profiles/437cwg3d.default/prefs.js

当命令运行时,我收到以下错误:

sed: /Users/admin/Library/Application: No such file or directory
sed: Support/Firefox/Profiles/437cwg3d.default/prefs.js: No such file or directory

我假设我需要以某种方式获取“find”命令以将输出路径用引号括起来,以便“sed”命令正确解析它?我在正确的道路上吗?我试图将 find 命令通过管道传递到 sed 以换行引号,但我无法让任何东西正常工作。请让我知道我是否应该以不同的方式处理这个问题。谢谢你。

4

2 回答 2

2

您不想for prefs in ...在从find. 有关为什么这不好的更完整解释,请参阅Greg 的关于解析 ls 的 wiki 页面。如果您可以使用 glob 匹配文件,则只能在 bash 中使用 for 循环,如果您想递归地执行此操作,这很困难。

如果你可以摆动它,它会更好,find ... -exec ...而不是使用它。也许是这样的:

find /Users -name prefs.js -exec sed -i.bak -e "s/$oldPref/$newPref/" {} \;

命令行对.sed找到的每个文件执行一次find。被{}文件名替换。Sed 的-i选项允许您就地运行它,而不需要标准输入/标准输出。检查手册页以获取使用详细信息。

于 2012-06-26T19:47:21.700 回答
1

(一粒盐:我是基于我对 linux 的经验)

我认为这与 sed 的关系不大,而与 for 循环数组的形成方式有关。当 find 的结果转换为数组时,Application 和 Support 之间的空格被视为分隔符。

有几种方法可以解决这个问题,但最简单的可能是更改 IFS 变量。IFS 变量是您的命令行解释器用来分隔字段的内部变量(更多信息)。您可以在运行 find 命令之前更改环境的 IFS 变量。

从这里修改的例子:

#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in `find /Users -name prefs.js`
do
  echo "$f"
done
# restore $IFS
IFS=$SAVEIFS
于 2012-06-26T19:53:14.073 回答