【问题标题】:Iterating through a file and replacing old values with new values using sed使用 sed 遍历文件并用新值替换旧值
【发布时间】:2015-08-01 07:54:47
【问题描述】:

我正在尝试编写一个脚本,其中 while 循环逐行读取文件,对该行的两个值执行命令(以获取两个新值),然后用两个新值替换两个旧值,然后移动到下一行。

例如txt文件example.txt包含以下数据:

 1432771200 != 1432800000 OPTION VALUE
 1432771200 != 1432800210 OPTION VALUE
 1432771200 != 1432800033 OPTION VALUE

然后我运行以下脚本:

 #!/bin/bash -x
 #
    while read line
    do
            arr=($line)
            CURRENTDATE=`h2e ${arr[0]}`
            PROPOSEDDATE=`h2e ${arr[2]}`
            echo $CURRENTDATE
            echo $PROPOSEDDATE
    #       echo $line |
            sed -i "s/${arr[0]}/$CURRENTDATE/"
    #       echo $line |
            sed -i "s/${arr[2]}/$PROPOSEDDATE/"
    done < /srg/pro/data/example.txt

我现在希望在 example.txt 文件中看到的是替换每一行的第一个和第三个值。所以它应该是这样的:

 Thu May 28 01:00:00.000 2015 BST != Thu May 28 09:00:00.000 2015 BST OPTION VALUE
 Thu May 28 01:00:00.000 2015 BST != Wed May 27 01:00:00.000 2015 BST OPTION VALUE
 Fri May 28 01:00:00.000 2015 BST != Fri May 29 06:00:00.000 2015 BST OPTION VALUE

等等等等..

当我使用 bash -x Interface.sh 运行 shell 脚本时,我得到了这个:

 read line
 + arr=($line)
 ++ h2e 1432771200
 + CURRENTDATE='1432771200.000  2015148  Thu May 28 01:00:00.000 2015 BST (1)'
 ++ h2e 1432800000
 + PROPOSEDDATE='1432800000.000  2015148  Thu May 28 09:00:00.000 2015 BST (1)'
  + echo 1432771200.000 2015148 Thu May 28 01:00:00.000 2015 BST '(1)'
   1432771200.000 2015148 Thu May 28 01:00:00.000 2015 BST (1)
   + echo 1432800000.000 2015148 Thu May 28 09:00:00.000 2015 BST '(1)'
   1432800000.000 2015148 Thu May 28 09:00:00.000 2015 BST (1)
 + sed -i 's/1432771200/1432771200.000  2015148  Thu May 28 01:00:00.000       2015 BST (1)/'
 sed: no input files
 + sed -i 's/1432800000/1432800000.000  2015148  Thu May 28 09:00:00.000   2015 BST (1)/'
 sed: no input files
 + read line
 + arr=($line)
 ++ h2e 1432771200
 + CURRENTDATE='1432771200.000  2015148  Thu May 28 01:00:00.000 2015 BST (1)'
 ++ h2e 1432800000
+ PROPOSEDDATE='1432800000.000  2015148  Thu May 28 09:00:00.000 2015 BST  (1)'
 + echo 1432771200.000 2015148 Thu May 28 01:00:00.000 2015 BST '(1)'
 1432771200.000 2015148 Thu May 28 01:00:00.000 2015 BST (1)
 + echo 1432800000.000 2015148 Thu May 28 09:00:00.000 2015 BST '(1)'
 1432800000.000 2015148 Thu May 28 09:00:00.000 2015 BST (1)
 + sed -i 's/1432771200/1432771200.000  2015148  Thu May 28 01:00:00.000 2015 BST (1)/'
 sed: no input files
+ sed -i 's/1432800000/1432800000.000  2015148  Thu May 28 09:00:00.000 2015 BST (1)/'
sed: no input files 

请帮忙!不知道如何解决这个问题!

【问题讨论】:

  • sed 是强制性的还是 awk 或其他工具可用?
  • 没有 sed 不是强制性的..
  • 因此,如果您的awk 本地副本具有内置的strftime() 功能,那么您可以在一个简短的awk 脚本中完成所有处理,并且速度和效率都非常好。 sed 仍然有可能以类似于您尝试的方式使用,但是您只需要一个 sed 命令,就像您尝试但已注释掉的 echo 的管道尾部一样,您需要使用 @ 987654332@ 两次(每个s 表达式一次),没有-i

标签: bash shell unix sed scripting


【解决方案1】:

读取命令可以读取将行拆分为字段:

outfile=/tmp/some_tmp_file_you_will_move
while read date1 marker date2 otherfields; do
    CURRENTDATE=`h2e ${date1}`
    PROPOSEDDATE=`h2e ${date2}`
    echo $CURRENTDATE
    echo $PROPOSEDDATE
    echo "${CURRENTDATE} ${marker} ${PROPOSEDDATE} ${otherfields}" >> ${outfile}
done < /srg/pro/data/example.txt

当您不需要在循环内看到 CURRENTDATE/PROPOSEDDATE 时,您可以将输出重定向到循环外以获得更好的性能:

outfile=/tmp/some_tmp_file_you_will_move
while read date1 marker date2 otherfields; do
    CURRENTDATE=`h2e ${date1}`
    PROPOSEDDATE=`h2e ${date2}`
    echo "${CURRENTDATE} ${marker} ${PROPOSEDDATE} ${otherfields}"
done < /srg/pro/data/example.txt > ${outfile}

注意:考虑使用 $(h2e ...) 而不是 ``

【讨论】:

  • 似乎请求更多的是关于如何使用此示例数据结构的通用信息,并且您的提议适用于此。如果结构稍有改变,您将修改几乎所有内容。
【解决方案2】:

使用您的批次(还有其他方式)

#!/bin/bash -x
 #
  cp /srg/pro/data/example.txt /tmp/temp.file

  cat /srg/pro/data/example.txt \
  | while read line
    do
            arr=($line)
            CURRENTDATE=`h2e ${arr[0]}`
            PROPOSEDDATE=`h2e ${arr[2]}`
            echo $CURRENTDATE
            echo $PROPOSEDDATE
    #       echo $line |
            sed -i "s/${arr[0]}\(.*\)${arr[2]}/${CURRENTDATE}\1${PROPOSEDDATE}/" /tmp/temp.file
    done

mv /tmp/temp.file /srg/pro/data/example.txt 
  • sed -i 无法在直播中使用,需要文件
  • 我使用临时文件来避免读取在循环内修改的同一文件时出现问题,这通常会产生意外结果(如空文件)
  • 这适用于您的示例,但它取决于您的数组的行结构和数据文件实际结构中的 sed 替换

【讨论】:

  • 问题似乎有好几次相同的 CURRENTDATE (和/或)建议时间,并且 sed 更改所有发生在您只想更改相同的地方。我调整 sed 动作以更符合您的需求(以对等值作为参考,而不是 2 次单拍)
  • 这似乎有点工作..但不完全正确..当我出于某种原因运行脚本时,它似乎多次读取该行并多次打印出替换值
  • 它仍在多次打印新值.. 即使更改了 sed 命令
  • 任何输出样本?我在这里重新测试(使用快速 h2e 将数字更改为字母),一切都很好
猜你喜欢
  • 2018-09-22
  • 2021-12-13
  • 2017-09-08
  • 2020-03-07
  • 2010-12-10
  • 2018-12-14
  • 1970-01-01
  • 2010-10-30
  • 2020-11-07
相关资源
最近更新 更多