使用sed查找,转换和替换行

时间:2011-01-03 09:40:48

标签: bash replace sed find

我不太了解bash脚本,我正在尝试开发一个bash脚本来执行此操作:

  • 我在同一目录中有很多.txt文件。
  • 每个.txt文件都遵循以下结构:
  
    

FILE1.TXT:
    < name>第一个操作< / name>
    <操作> 21< /操作>
    <开始时间> 1292435633< /开始时间>
    <结束时间> 1292435640< /结束时间>

    < name>第二个操作< / name>
    <操作> 21< /操作>
    <开始时间> 1292435646< /开始时间>
    <结束时间> 1292435650< /结束时间>

  
  • 我想搜索每个< StartTime>行并将其转换为标准日期/时间格式(不是unix时间戳),但保留结构< StartTime> 2010-12-15 22:52< / StartTime&gt ;,例如。这可能是搜索/替换的功能,使用sed?我想我可以使用我发现的这些功能:date --utc --date“1970-01-01 $ 1 sec”“+%Y-%m-%d%T”

  • 我想对< EndTime>做同样的事情。标签

  • 我应该对目录中的所有* .txt文件执行此操作。

我尝试使用sed,但没有想要的结果。正如我所说,我不太了解bash脚本,所以任何帮助都会受到赞赏。

感谢您的帮助!

此致

2 个答案:

答案 0 :(得分:1)

sed无法进行日期转换;相反,我建议你使用更合适的工具,如awk:

echo '<StartTime>1292435633</StartTime>' | awk '{
    match($0,/[0-9]+/);
    t = strftime("%F %T",substr($0,RSTART,RLENGTH),1);
    sub(/[0-9]+/,t)
} 
{print}'

如果您的输入文件每行有一个标记,就像在结构示例中一样,它应该完美无缺。

如果您需要为每个.txt文件重复操作,只需使用shell:

for file in *.txt; do
    awk '/^<[^>]*Time>/{
        match($0,/[0-9]+/);
        t = strftime("%F %T",substr($0,RSTART,RLENGTH),1);
        sub(/[0-9]+/,t)
    } 1' "$file" >"$file.new"
    # mv "$file.new" "$file"
done

与之前的代码相比,我做了两个小的改动:

  • 添加条件/ ^&lt; [^&gt;] *时间&gt; /检查当前行是否以
  • 开头
  • 将{print}转换为较短的'1'

如果以.new结尾的文件包含您期望的结果,则可以取消注释包含mv的行。

答案 1 :(得分:0)

使用grep:

while read line;do
    if [[ $line == *"<StartTime>"* || $line == *"<EndTime>"* ]];then
        n=$(echo $line | grep -Po '(?<=(>)).*(?=<)')
        line=${line/$n/$(date -d @$n)}
    fi

    echo $line >> file1.new.txt
done < file1.txt

$ cat file1.new.txt 
<name>first operation</name>
<operation>21</operation>
<StartTime>Wed Dec 15 18:53:53 CET 2010</StartTime>
<EndTime>Wed Dec 15 18:54:00 CET 2010</EndTime>

<name>second operation</name>
<operation>21</operation>
<StartTime>Wed Dec 15 18:54:06 CET 2010</StartTime>
<EndTime>Wed Dec 15 18:54:10 CET 2010</EndTime>