循环遍历文件并使用sed替换每一行

时间:2017-04-12 11:18:19

标签: linux bash loops unix sed

我有以下bash脚本:

while IFS= read -r line; do
      line=$(echo $line | sed "s/\'/\'\'/")

      [[ $line =~ ^\<ID\>(.*) ]] && printf "${BASH_REMATCH[1]}"
done <  <(dos2unix < file)

没有dos2unix的脚本的EDITED版本:

while IFS= read -r line && line=${line%$'\r'}; do
   [[ $line =~ ^\<ID\>(.*) ]] && printf "${BASH_REMATCH[1]}"
done < file

我想用&#34;文件&#34;中的每个撇号替换。有2个撇号 BEFORE 我循环通过它。我怎样才能做到这一点?我对任何有关这两个版本的建议表示感谢。 重要 NOT 允许修改原始文件!!

2 个答案:

答案 0 :(得分:0)

这是sed单独的工作:

sed 's/\r$//;s/\'/\'\'/g;s/^<ID>\(.*\)/\1/p;d' < file

步骤如下:

  1. sed接受以换行符,分号分隔的多个命令或以多个-e选项分配。
  2. sed 's/\r$//;删除每行末尾的CR,如dos2unix
  3. 添加到g的{​​{1}}标记表示替换行中的所有出现次数;默认是只替换一个。
  4. s/\'/\'\'/相当于bash正则表达式匹配,最后的s/^<ID>\(.*\)/\1/标记使sed打印匹配的行 now ,因为
  5. p命令会删除该行,因此默认情况下不会打印(您可以使用d选项执行此操作)。
  6. 另一方面,我的zsh不接受-n中的\',所以我可能会写一下

    '

    它应该是等效的,只需切换引号样式,单独选项和sed -n -e 's/\r$//' -e "s/'/''/g" -e 's/^<ID>\(.*\)/\1/p' 而不是最终-n

答案 1 :(得分:0)

虽然这不是&#34;解决方案&#34; (你的问题不清楚你的代码中有什么不起作用),你当然应该避免为每一行调用sed。它不是&#34;错误&#34;在产生不正确结果的意义上,但是它应该避免它慢得多。有一些方法可以更快,更简单地进行编码。

这样做:

while IFS= read -r line; do
      [[ $line =~ ^\<ID\>(.*) ]] && printf "${BASH_REMATCH[1]}"
done <  <(dos2unix < file | sed "s/\'/\'\'/")