使用bash sed替换文件中的文件名变量

使用bash sed替换文件中的文件名变量,bash,sed,Bash,Sed,我试图在index.html中查找字符串“js/main.js”和“js/main.min.js?YYYYMMDDHHMMSS”,并使用以下命令替换为新的“js/main.min.js?YYYYMMDDHHMMSS”: File='js/main.js' MinFile='js/main.min.js' datestr=$(date +%Y%m%d%H%M%S) echo sed -i.bak 's,\"'"$File"'\"|\"'"$MinFile"'\?.*?\",\"'"$MinFil

我试图在index.html中查找字符串“js/main.js”和“js/main.min.js?YYYYMMDDHHMMSS”,并使用以下命令替换为新的“js/main.min.js?YYYYMMDDHHMMSS”:

File='js/main.js'
MinFile='js/main.min.js'

datestr=$(date +%Y%m%d%H%M%S)
echo sed -i.bak 's,\"'"$File"'\"|\"'"$MinFile"'\?.*?\",\"'"$MinFile"'?'"$datestr"'\",g' index.html
errorMsg=$(sed -i.bak 's,\"'"$File"'\"|\"'"$MinFile"'\?.*?\",\"'"$MinFile"'?'"$datestr"'\",g' index.html)
但是它在“js/main.js”和“js/main.min.js?YYYYMMDDHHMMSS”上不匹配您有:

errorMsg=$(sed -i.bak 's,.$foo.,.$bar.,g' file)
如果要在sed中使用shell变量,应使用
(双引号)而不是
单引号。shell变量不会在单引号之间展开

尝试以下方法:

errorMsg=$(sed -i.bak "s,$File..$MinFile...,...$datestr...,g" index.html)
输入:

<script src="js/main.js"></script> <script src="js/main.min.js?1234567890"></script>

输出:

<script src="js/main.min.js?20130520143027"></script> <script src="js/main.min.js?20130520143027"></script>

您可能需要考虑下一个
perl
脚本

use 5.014;
use warnings;
use HTML::TreeBuilder;
use POSIX qw(strftime);

my $html = HTML::TreeBuilder->new_from_file(\*DATA);
$html->no_expand_entities(1);

my $now = strftime "%Y%m%d%H%M%S", localtime;
foreach my $script ($html->find_by_tag_name('script')) {
    $script->{src} = "js/main.min.js?$now" if( $script->{src} =~ m{^(js/main.js|js/main.min.js)} );
}
print $html->as_HTML(undef, "\t");

__DATA__
<html>
<head>
    <script type="text/javascript" src="js/main.js"></script>
    <script type="text/javascript" src="js/nomain.js"></script>
</head>
<body>
    <p>The "js/main.js" script is used here</p>
</body>
</html>
使用5.014;
使用警告;
使用HTML::TreeBuilder;
使用POSIXQW(strftime);
my$html=html::TreeBuilder->new\u from\u文件(\*数据);
$html->no_expand_实体(1);
my$now=strftime“%Y%m%d%H%m%S”,本地时间;
foreach my$script($html->find_by_tag_name('script')){
$script->{src}=“js/main.min.js?$now”如果($script->{src}=~m{^(js/main.js | js/main.min.js)});
}
打印$html->as_html(未定义“\t”);
__资料__
这里使用“js/main.js”脚本

将打印

<html>
    <head>
        <script src="js/main.min.js?20130520221648" type="text/javascript"></script>
        <script src="js/nomain.js" type="text/javascript"></script>
    </head>
    <body>
        <p>The "js/main.js" script is used here</body>
</html>

这里使用“js/main.js”脚本

因此,更改
中的所有main.js问题在于如何使用转义字符解析语法:

  • 不应该逃走的
  • 管子应该漏出来
  • 应转义任何滚动括号
看 是什么导致了我的解决方案

sed命令最终看起来像这样,并在bash中按预期工作:

$(sed -i "s,\"$File\"\|\"$MinFile?[0-9]\{14\}\",\"$MinFile?$datestr\",g" index.html)

应匹配中的src属性:也尝试了失败:echo-sed-i.bak“s、\“$File\”、\“$MinFile\?*?*?\”、\“$MinFile?$datestr\”、g“index.html errorMsg=$(sed-i.bak”s、\“$File\”、\“$MinFile\?*?*”、\“$MinFile?$datestr\”、g“index.html)是的..在我的搜索中,这是一个常见问题..但请注意,变量用双引号括起来:echo计算为sed-i.bak s、“js/main.js”|“js/main.min.js\?*”、“js/main.min.20130520140000”、g index.html。以下变量也不起作用:echo-i.bak s、\“$File\”、“$MinFile\?*”、“$MinFile\?*”、“$datestr\”、g“index.html errorMsg”=$(sed-i.bak“s、\“$File\”、\“$MinFile\?*?*?”、\“$MinFile?$datestr\”、g“index.html)输入:输出:我不想只替换日期通常我想用缩小版本替换特定文件的特定引用,并添加日期时间的哈希作为查询参数
$(sed -i "s,\"$File\"\|\"$MinFile?[0-9]\{14\}\",\"$MinFile?$datestr\",g" index.html)