我有以下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 允许修改原始文件!!
答案 0 :(得分:0)
这是sed
单独的工作:
sed 's/\r$//;s/\'/\'\'/g;s/^<ID>\(.*\)/\1/p;d' < file
步骤如下:
sed
接受以换行符,分号分隔的多个命令或以多个-e
选项分配。sed 's/\r$//;
删除每行末尾的CR,如dos2unix
。g
的{{1}}标记表示替换行中的所有出现次数;默认是只替换一个。s/\'/\'\'/
相当于bash正则表达式匹配,最后的s/^<ID>\(.*\)/\1/
标记使sed打印匹配的行 now ,因为p
命令会删除该行,因此默认情况下不会打印(您可以使用d
选项执行此操作)。另一方面,我的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/\'/\'\'/")