如何将命令的结果包装在引号中以将其传递给另一个命令?

时间:2012-06-26 19:33:32

标签: macos firefox for-loop sed find

这适用于Apple平台。我的最终目标是查找并替换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

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

/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来包装引号,但是我无法正常工作。如果我不同意,请告诉我。谢谢。

2 个答案:

答案 0 :(得分:2)

您不希望在for prefs in ...输出的文件列表中find。有关错误原因的更完整说明,请参阅Greg's wiki page about parsing ls。如果你可以使用glob匹配文件,你只能在bash中使用for循环,如果你想以递归的方式进行,这很难。

如果你能摆动它,那就更好了,而不是使用find ... -exec ...。也许是这样的事情:

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

sed找到的每个文件执行find命令行一次。 {}被文件名替换。 Sed的-i选项允许您就地运行它,而不是需要stdin / stdout。查看手册页以了解使用详情。

答案 1 :(得分:1)

(谷物盐:我的基础是我对linux的经验)

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

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

来自here的修改示例:

#!/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