String AIX文件中的最佳字符串替换

String AIX文件中的最佳字符串替换,string,replace,awk,sed,find,String,Replace,Awk,Sed,Find,我需要从通讯组列表中的几个文件中删除大约40封电子邮件。 一个地址可能出现在不同的文件中,需要从所有文件中删除。 我在一个目录下工作,其中有几个.sh文件,也有几行 我在几个测试文件中做过类似的工作: find . -type f -exec grep -li ADDRESS_TO_FIND {} 2>/dev/null \; | xargs sed -i 's/ADDRESS_TO_REMOVE/ /g' * 它工作得很好,但一旦我在真实的文件中尝试了它,它需要很长时间,而且只是停留

我需要从通讯组列表中的几个文件中删除大约40封电子邮件。 一个地址可能出现在不同的文件中,需要从所有文件中删除。 我在一个目录下工作,其中有几个.sh文件,也有几行

我在几个测试文件中做过类似的工作:

find . -type f -exec grep -li  ADDRESS_TO_FIND {} 2>/dev/null \; | xargs sed -i 's/ADDRESS_TO_REMOVE/ /g' *
它工作得很好,但一旦我在真实的文件中尝试了它,它需要很长时间,而且只是停留在那里。我需要在不同的服务器上运行它,这是我想要优化它的主要原因

我试过这样做:

find . -type f -name '*sh' 2>/dev/null | xargs grep ADDRESS_TO_FIND
awk '{print substr($0,1,10)}'
但这将再次出现:

./FileContainingAddress.sh:ADDRESS_TO_FIND
如何添加以下内容:

find . -type f -name '*sh' 2>/dev/null | xargs grep ADDRESS_TO_FIND
awk '{print substr($0,1,10)}'
但是在“
”之前把所有的东西都还给我


我可以从这里开始做其余的事情,但是还没有找到如何修剪这部分的方法。在回顾你的问题之后,我注意到了一些可能非常重要的事情:

find -type f -exec grep -li ADDRESS {} \; | xargs sed -i 's/ADDRESS/ /g' *
# here! -----------------------------------------------------------------^
星号正在展开,因此sed行正在目录中的每个文件上运行


假设你的问题中没有输入错误,我相信这是你表现不佳的原因。你应该移除它

您可以使用
-exec
作为
find
中的谓词,只要您不使用多文件
+
版本,这意味着您可以提供多个
-exec
子句,每个子句都将取决于前一个子句的成功与否。这种样式将避免构建文件名列表,这使得它在文件名中包含奇数字符时更加健壮

例如:

find . -type f -name '*sh' \
     -exec grep -qi ADDRESS_TO_FIND {} \; \
     -exec sed -i 's/ADDRESS_TO_FIND/ /g' {} \;
您可能希望将地址作为一个参数提供,而不是必须键入两次,除非您确实希望两个实例不同(
address\u to\u FIND
address\u to\u REMOVE
):


(注意
/
的参数中的
/
。我将把使
sed
更健壮作为一个练习。)

使用awk-F找到了一个解决方案:“{print$1}”最后一个命令是:find-键入f-name'*1'2>/dev/null | xargs grep ADDRESS | awk-f:'{print$1}'| xargs sed-i's/ADDRESS//g'*是,
awk-f:'{print$1}'
将在冒号之前打印该部分,但您可以使用
-l
切换到grep完全避免它。我认为你最初的尝试是正确的。正如我在回答中提到的那样,应该删除命令末尾的
*
。+1我不知道您可以像那样链接
-exec
命令,非常整洁。虽然我想您也可以使用
find-print0
xargs-0
来处理有问题的文件名。@TomFenech:
find-print0
xargs-0
不是Posix。无论如何,假设您有Gnu
find
xargs
,您可以按文件名进行初始查找,但仍然必须从
grep
输出文件名。关于
find
,Posix说,“这里考虑了
-print0
,但没有采用。使用空终止符意味着任何要处理find的-print0输出的实用程序都必须添加一个新选项来解析它现在正在读取的空终止符。”。
-exec。。。。{}+
表单被采用了。@TomFenech:
sed-i
也是非Posix的,所以我不知道它在AIX上是如何工作的。如果它的工作方式与Gnu版本类似,那么您可以在我的回答中使用
{}+
作为
-exec sed
子句,这将更有效率,因为它只会启动一个
sed
.sed-我不会在标准AIX上工作。您需要重定向到一个临时文件,而不是cp或mv。有时,将同一文件作为输入和输出进行双重重定向是可行的,但结果通常是不可预测的或空的。@NeronLevel:将同一文件作为输入和输出进行重定向是不可行的,因为shell将在启动
sed
实用程序之前截断输出文件。AIX
sed
没有
-i
选项并不奇怪,但它在OP中,这表明提问者有一个版本的
sed
支持
-i
。在AIX上安装gnused并非不可能。