我尝试进行动态查找/替换,其中来自find的匹配组在替换中被操作。
testfile的:
…
other text
base64_encode_SOMEPATH_ something
other(stuff)
text base64_encode_SOMEOTHERPATH_
…
这样的事情:
sed -i "" -e "s/(base64_encode_(.*)_)/cat MATCH | base64/g" testfile
会输出类似的内容:
…
other text
U09NRVNUUklORwo= something
other(stuff)
text U09NRU9USEVSU1RSSU5HCg==
…
答案 0 :(得分:2)
awk '!/^base64_encode_/ { print } /^base64_encode_/ { fflush(); /^base64_encode_/ { fflush(); sub("^base64_encode_", ""); sub("_$", ""); cmd = "base64" ; print $0 | cmd; close(cmd); }' testfile > testfile.out
这表示不加改变地打印不匹配的行。
使用awk
函数sub()
更改匹配行以提取要编码的字符串,然后将其传送到base64
命令,该命令将结果打印到stdout。
需要fflush
调用,以便在awk
输出出现之前刷新base64
的所有先前输出,确保不重新排序行。
修改强>:
正如评论中所指出的,测试每一行两次以匹配一个模式并且不匹配相同的模式并不是很好。这个单一动作处理所有行:
{
if ($0 !~ "base64_encode_")
{
print;
next;
}
fflush();
sub("^.*base64_encode_", "");
sub("_$", "");
cmd = "base64";
print $0 | cmd;
close(cmd);
}
答案 1 :(得分:2)
根据您的新要求更新。现在使用GNU awk为第3个arg匹配()以方便:
$ awk 'match($0,/(.*)base64_encode_([^_]+)_(.*)/,arr) {
cmd = "base64 <<<" arr[2]
if ( (cmd | getline rslt) > 0) {
$0 = arr[1] rslt arr[3]
}
close(cmd)
} 1' file
…
other text
U09NRVNUUklORwo= something
other(stuff)
text U09NRU9USEVSU1RSSU5HCg==
…
如果您要使用getline
,请务必阅读并理解http://awk.info/?tip/getline。
如果你不能安装GNU awk(但是你真的,真的会因为尝试这样做而受益)那么这样的东西可以用于任何现代的awk:
$ awk 'match($0,/base64_encode_[^_]+_/) {
arr[1] = substr($0,1,RSTART-1)
arr[2] = arr[3] = substr($0,RSTART+length("base64_encode_"))
sub(/_.*$/,"",arr[2])
sub(/^[^_]+_/,"",arr[3])
cmd = "base64 <<<" arr[2]
if ( (cmd | getline rslt) > 0) {
$0 = arr[1] rslt arr[3]
}
close(cmd)
} 1' file
我说“类似”,因为你可能需要调整substr()和/或sub()args如果它们稍微关闭,我还没有测试过。