我正在尝试编写一个shell脚本,用一个新值替换文件中的几行文本

时间:2012-05-06 16:17:56

标签: regex bash shell sed

规则是:

  • 删除除最后一行以外的所有行: link href =
  • 替换之后的内容: href = ,之前: .css 你好世界
  • 文件名
  • 周围必须没有引号,单引号或双引号

一些例子:

这是一个带引号的源文件:

<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/master.css">

这是新的源文件:

<link rel="stylesheet" href="hello-world.css">

这是一个没有引号的源文件:

<link rel=stylesheet href=css/reset.css>
<link rel=stylesheet href=css/master.css>

这是新的源文件:

<link rel=stylesheet href=hello-world.css>

不需要维护文件名的路径。然而,它不能使用&lt;&gt;用于确定需要编辑的内容的括号或空格,因为写入该行的模板语言可能不使用括号或空格。唯一能保持一致的是 href = [filename] .css

我的bash / sed / regex技能很糟糕,但这些工具似乎可能会以合适的方式完成工作?我该怎么做呢?

修改

为了澄清,最终结果将使包含链接和href =单独的行的上方和下方的所有内容都保留。想象一下,源文件是一个html文件或任何其他模板文件,如下所示:

<html>
  <head>
    <title>Hello</title>
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/master.css">
  </head>

  <body><p>...</p></body>
</html>

它将改为:

<html>
  <head>
    <title>Hello</title>
    <link rel="stylesheet" href="css/hello-world.css">
  </head>

  <body><p>...</p></body>
</html>

CSS文件的路径也可能是。

../foo/bar.css
http://www.hello.com/static/css/hi.css
/yep.css
ok.css

新文件的路径将作为bash脚本的参数提供,因此正则表达式应该删除路径。

3 个答案:

答案 0 :(得分:3)

discussion in chat之后,使用PHP作为命令行脚本的一个解决方案看起来像这样 -

#! /usr/bin/php 
<?php

    $options = getopt("f:r:");
    $inputFile = $options['f'];
    $replacement = $options['r'];
    // read entire contents of input file 
    $inputFileContents = file_get_contents($inputFile);
    // setup the regex and execute the search
    $pattern = '/.*link.*href=["|\']?(.*[\\\|\/]?.*)\.css["|\']?.*/';
    preg_match_all($pattern, $inputFileContents, $matches);
    // remove last occurance of regex 
    // these are the lines we'll want to hang onto
    $matchedLines = $matches[0];
    array_pop($matchedLines);
    // isolate the last css file name
    $matchedFileName = array_pop($matches[1]);
    // first substitution replaces all lines with <link> with 
    // an empty string (deletes them)
    $inputFileContents = str_replace($matchedLines,'',$inputFileContents);
    // second substitution replaces the matched file name
    // with the desired string
    $inputFileContents = str_replace($matchedFileName,$replacement,$inputFileContents);
    //*/
      // save to new file for debugging
      $outputFileName = "output.html";
      $outputFile = fopen($outputFileName,'w+');
      fwrite($outputFile,$inputFileContents);
      fclose($outputFile);
    /*/
      // save changes to original file
      $origFile = fopen($inputFile,'w+');
      fwrite($origFile,$inputFileContents);
      fclose($origFile);
    //*/
    exit();
?>

您可以从命令行执行此脚本,如此 -

$ php thisScript.php -f "input.html" -r "hello-world" 
  • -f是我们正在解析的输入文件。
  • -r是css文件名的替换字符串(在此示例中为“hello-world”)。

答案 1 :(得分:1)

具体回答,对于这种情况:

如果您包含两次相同的css文件,则不会对用户造成任何伤害 所以你可以用css / hello-world.css替换css / reset.css和css / master.css。

可能有更好的方法,但我发现这是一个快速的方法。它将专门用于此案例&amp;如果您想要替换<script>或其他标签,请不要这样做。

答案 2 :(得分:0)

尝试在css之前包含文件的第一部分,然后在css下面包含文件的其余部分,并在中间,回显正确的css行