Jen*_*Hoo 5 unix bash shell grep sed
我在寻找正确的命令来搜索和查找 Unix 上包含 XML 文件的多个 ZIP 文件中的字符串时遇到问题。
我能够在多个 ZIP 文件中找到搜索字符串,但未能成功替换查找内容并替换该字符串。
不幸的是,这不太有效。一旦找到解压缩文件(到临时位置)的字符串,我就尝试使用 grep 和 sed 命令。但我可能错误地认为我可以编辑临时文件?
oldAddress='<ns1:line1/>'
newAddress='<ns1:line1>somestring</ns1:line1>'
for file in *.zip; do
unzip -c "$file" | grep -q "<ns1:line1/>" | xargs -l {} sed -i 's/$oldAddress/$newAddress/g'
done
Run Code Online (Sandbox Code Playgroud)
提前致谢。
首先,虽然使用全局变量很诱人,但 bash 还支持以下循环样式:
while read line ; do echo $line; done < <(find . -iname 'file*zip')
Run Code Online (Sandbox Code Playgroud)
其次,您可以使用zipgrep搜索文件,然后只解压那些真正需要解压的文件。这将导致文件两次放气。一次用于 grep,一次用于解压那些真正需要解压的人。但是,这将使我们无需将多余的文件压缩回来。
第三,您要搜索两次,对于大文件或许多文件,这会慢两倍:
grep -q "<ns1:line1/>" | xargs -l {} sed -i 's/$oldAddress/$newAddress/g'
Run Code Online (Sandbox Code Playgroud)
相反,您可以仅解压缩那些匹配的文件,然后仅使用 sed 一步完成搜索和替换。
# From within a (bash) script you need to use double quotes instead of singel qoutes to expand the variable
newAddress="<ns1:line1>somestring</ns1:line1>"
oldAddress="<ns1:line1/>"
for fname in *.zip
do
zipgrep -q $oldAddress $fname;
if [ $? -eq 0 ]; then
filename="${fname%.*}"
unzip -qp $fname | sed -e 's#'$oldAddress'#'$newAddress'#g' > $filename
zip $filename.zip $filename
fi
done
Run Code Online (Sandbox Code Playgroud)
这是一个创建测试数据的 for 循环:
for i in {1..4} ; do touch file$i; done
while read line ; do
echo '<ns1:line1/>' > $line;
zip $line.zip $line
rm $line
done < <(find . -iname 'file*')
Run Code Online (Sandbox Code Playgroud)