如何使长 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
现在这是我脚本的 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