如何使长 SED 脚本更精简,代码更易读

How to make long SED script leaner and more readable as code

现在这是我脚本的 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' ""

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

看看 this question 说明

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

"Splitting on several lines with backslash does work if new lines are not indented."

这是 GNU awk 的等价物:

awk -i inplace '{
   [=10=] = gensub(/<(\/?Codec>/,"<\1inm:Video-codec>")
   [=10=] = gensub(/<(\/?)Duration_String4>","<\1inm:D-Duration>")
   [=10=] = gensub(/<(\/?)Width>","<\1inm:Width>")
   [=10=] = gensub(/<(\/?)FileExtension>","<\1inm:Wrapper>")
   print
}' ""

您可以多次指定-e

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' ""

这可能会导致您使用 bash 数组进行重构:

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[@]}" ""

或者,使用 -f 选项和进程替换:

sed -f <( printf "%s\n" "${commands[@]}" ) ""

首先分部分设置 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:备注:使用小写的 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}" ""

您的下一步可能是创建一个函数来解析配置文件。
配置文件可能包含类似

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

(with * a nice FieldSep) 并让您的函数处理反斜杠。

甚至更好:告诉您的函数应该始终添加结束标记替换, 并制作一个像

这样的配置文件
Codec/inm:Video-codec
Duration_String4/inm:D-Duration
Width/inm:Width
FileExtension/inm:Wrapper