1

这是我的脚本的 sed 部分:

sed -i -e 's/<Codec>/<inm:Video-codec>/g;s/<Duration_String4>/<inm:D-Duration>/g;s/<Width>/<inm:Width>/g;s/<\/Codec>/<\/inm:Video-codec>/g;s/<\/Duration_String4>/<\/inm:D-Duration>/g;s/<\/Width>/<\/inm:Width>/g;s/<FileExtension>/<inm:Wrapper>/g;s/<\/FileExtension>/<\/inm:Wrapper>/g' "$1"

它只会越来越长。有没有办法让这段代码更具可读性?我可以为每个替换换一个新行,还是必须启动一个新的 sed 命令才能做到这一点?

4

4 回答 4

2

首先分部分设置 sedstring:

SEDSTR='s/<Codec>/<inm:Video-codec>/g'
SEDSTR="$SEDSTR;"'s/<Duration_String4>/<inm:D-Duration>/g'
SEDSTR="$SEDSTR;"'s/<Width>/<inm:Width>/g'
SEDSTR="$SEDSTR;"'s/<\/Codec>/<\/inm:Video-codec>/g'
SEDSTR="$SEDSTR;"'s/<\/Duration_String4>/<\/inm:D-Duration>/g'
SEDSTR="$SEDSTR;"'s/<\/Width>/<\/inm:Width>/g'
SEDSTR="$SEDSTR;"'s/<FileExtension>/<inm:Wrapper>/g'
SEDSTR="$SEDSTR;"'s/<\/FileExtension>/<\/inm:Wrapper>/g'

sed -i -e "$SEDSTR" "$1"

编辑 1:备注:使用小写的 shell 变量更好。编辑2:附加可以完成+=

sedstr='s/<Codec>/<inm:Video-codec>/g'
sedstr+=';s/<Duration_String4>/<inm:D-Duration>/g'
sedstr+=';s/<Width>/<inm:Width>/g'
sedstr+=';s/<\/Codec>/<\/inm:Video-codec>/g'
sedstr+=';s/<\/Duration_String4>/<\/inm:D-Duration>/g'
sedstr+=';s/<\/Width>/<\/inm:Width>/g'
sedstr+=';s/<FileExtension>/<inm:Wrapper>/g'
sedstr+=';s/<\/FileExtension>/<\/inm:Wrapper>/g'

sed -i -e "${sedstr}" "$1"

您的下一步可能是创建一个解析配置文件的函数。
配置文件可能有如下行

<Codec>*<inm:Video-codec>
</Codec>*</inm:Video-codec>

(使用 * 一个不错的 FieldSep)并让您的函数处理反斜杠。

甚至更好:告诉你的函数应该总是添加一个结束标签替换,并制作一个像这样的配置文件

Codec/inm:Video-codec
Duration_String4/inm:D-Duration
Width/inm:Width
FileExtension/inm:Wrapper
于 2015-08-22T22:01:17.473 回答
1

这是 GNU awk 等价物:

awk -i inplace '{
   $0 = gensub(/<(\/?Codec>/,"<\\1inm:Video-codec>")
   $0 = gensub(/<(\/?)Duration_String4>","<\\1inm:D-Duration>")
   $0 = gensub(/<(\/?)Width>","<\\1inm:Width>")
   $0 = gensub(/<(\/?)FileExtension>","<\\1inm:Wrapper>")
   print
}' "$1"
于 2015-08-22T21:00:56.580 回答
0

看看这个问题,说明

sed 's'/\
'[long1]'\
'[long2]'\
'/'\
'[long3]'\
'[long4]'\
'/' file.txt

“如果没有缩进新行,则使用反斜杠拆分多行确实有效。”

于 2015-08-22T20:55:44.527 回答
0

You can specify -e multiple times:

sed -i -e 's/<Codec>/<inm:Video-codec>/g' \
       -e 's/<Duration_String4>/<inm:D-Duration>/g' \
       -e 's/<Width>/<inm:Width>/g' \
       -e 's/<\/Codec>/<\/inm:Video-codec>/g' \
       -e 's/<\/Duration_String4>/<\/inm:D-Duration>/g' \
       -e 's/<\/Width>/<\/inm:Width>/g' \
       -e 's/<FileExtension>/<inm:Wrapper>/g' \
       -e 's/<\/FileExtension>/<\/inm:Wrapper>/g' "$1"

which might lead you to refactor using bash arrays:

commands=(
       's/<Codec>/<inm:Video-codec>/g'
       's/<Duration_String4>/<inm:D-Duration>/g'
       's/<Width>/<inm:Width>/g'
       's/<\/Codec>/<\/inm:Video-codec>/g'
       's/<\/Duration_String4>/<\/inm:D-Duration>/g'
       's/<\/Width>/<\/inm:Width>/g'
       's/<FileExtension>/<inm:Wrapper>/g'
       's/<\/FileExtension>/<\/inm:Wrapper>/g'
)

for cmd in "${commands[@]}"; do
    options+=(-e "$cmd")
done

sed "${options[@]}" "$1"

Or, using the -f option and a process substitution:

sed -f <( printf "%s\n" "${commands[@]}" ) "$1"
于 2015-08-22T21:35:03.530 回答