从 xml 文件中读取一个 .sh 文件
Make a .sh file reading from a xml file
我有一个文件 channels.xml 有一个这样的结构,长 4000 行
<!--begin_channel-->
Rai 1.png
<!--end_channel-->
Rai 1 +2HD.png
Rai 1 +1HD.png
<!--begin_channel-->
Rai 2.png
<!--end_channel-->
Rai 2 +2HD.png
Rai 2 +1HD.png
.
.
我需要制作一个这样的文件channels.sh:
cp /cygdrive/c/ProgramData/ServerCare/data/picons/Rai_1.png /cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/Rai_1_+2HD.png
cp /cygdrive/c/ProgramData/ServerCare/data/picons/Rai_1.png /cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/Rai_1_+1HD.png
cp /cygdrive/c/ProgramData/ServerCare/data/picons/Rai_2.png /cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/Rai_2_+2HD.png
cp /cygdrive/c/ProgramData/ServerCare/data/picons/Rai_2.png /cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/Rai_2_+1HD.png
我需要用 cygwin 来做,我有一个脚本可以在 ubuntu 下做,但是用 cygwin 不工作。这是脚本:
#!/bin/bash
#colori
RED='3[0;31m'
GREEN='3[0;32m'
NC='3[0m'
if [ $# -ne 4 ]
then
echo -e "${RED}ERRORE${NC}, inserire [=13=] filein fileout pathlogo_from pathlogo_to"
echo -e "${RED}Ricorda${NC} le enstensioni!"
exit 0
fi
if [ -f ]
then
echo -n -e "File esistente, vuoi ${RED}sovrascrivere${NC}?(Y/n) "
read scelta
if [ $scelta != 'Y' ]
then
exit 0
else
rm
fi
fi
awk '/\<!--begin_channel--\>/{flag=1; next} /\<!--end_channel--\>/{flag=0} flag' > temp
while read line
do
awk "/$line/,/<!--begin_channel-->/ " | grep -v "$line" | grep -v "^<" > tmp
for channel in `cat tmp`
do
channel=`echo $channel | tr ")" "_" | tr "(" "_" | tr ":" "_"`
echo "cp /$line /$channel"
done
done <temp >>
rm temp
rm tmp
echo -e "${GREEN}File creato correttamente${NC}"
我认为错误与这一行有关
awk "/$line/,/<!--begin_channel-->/ " | grep -v "$line" | grep -v "^<" > tmp
到运行它我用命令
{ bash } »./script.sh channels.xml channels.sh /cygdrive/c/ProgramData/ServerCare/data/picons/ /cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/
有人可以帮我修复它或写一个新的吗?
@Tapiocapioca:尝试:您可以根据您的要求将输出输出到文件或脚本中,然后让我们知道。
awk -vlines=$(cat Input_file | wc -l) -vsource="/cygdrive/c/ProgramData/ServerCare/data/picons/" -vtarget="/cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/" '/<!--end_channel/{getline;while([=10=] !~ /<!--begin_channel/){print "cp " source SOURCE OFS target [=10=];if(NR==lines){exit};getline}} /<!--begin_channel/{getline;SOURCE=[=10=];next}' Input_file
NON-one线性解的形式也如下:
awk -vlines=$(cat Input_file | wc -l) -vsource="/cygdrive/c/ProgramData/ServerCare/data/picons/" -vtarget="/cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/" '
/<!--end_channel/{
getline;
while([=11=] !~ /<!--begin_channel/){
print "cp " source SOURCE OFS target [=11=];
if(NR==lines){
exit
};
getline
}
}
/<!--begin_channel/{
getline;
SOURCE=[=11=];
next
}
' Input_file
虽然我不喜欢蛮力,但这里有一些选择:
awk -vsource="/cygdrive/c/ProgramData/ServerCare/data/picons/"
-vtarget="/cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/"
'/begin_channel/{getline src;gsub(/ /,"_",src)}
/end_channel/{for(i=1;i<3;i++){
getline dest;gsub(/ /,"_",dest);
print "cp",source src,target dest}}' xml_file
上面的好处是,一旦您对输出正确感到满意,您只需在打印和 "cp" 之间放置一个竖线 (|),它就会将输出传送到shell 并进行复制,或者如果您出于某种原因确实需要制作中间脚本,请将管道放在外面并简单地将 awk 重定向到 channels.sh
这里还有一个 bash 替代方案:
xml=""
script=""
src_path=""
dest_path="${src_path}duplicati/"
get_src=0
get_dest=0
while read -r line
do
if [[ "$line" =~ begin_channel ]]
then
get_src=1
get_dest=0
elif [[ "$line" =~ end_channel ]]
then
get_dest=1
get_src=0
else
(( get_src == 1 )) && src="${src_path}${line// /_}"
if (( get_dest == 1 ))
then
dest="${dest_path}${line// /_}"
echo "cp $src $dest"
fi
fi
done<"$xml">"$script"
我有一个文件 channels.xml 有一个这样的结构,长 4000 行
<!--begin_channel-->
Rai 1.png
<!--end_channel-->
Rai 1 +2HD.png
Rai 1 +1HD.png
<!--begin_channel-->
Rai 2.png
<!--end_channel-->
Rai 2 +2HD.png
Rai 2 +1HD.png
.
.
我需要制作一个这样的文件channels.sh:
cp /cygdrive/c/ProgramData/ServerCare/data/picons/Rai_1.png /cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/Rai_1_+2HD.png
cp /cygdrive/c/ProgramData/ServerCare/data/picons/Rai_1.png /cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/Rai_1_+1HD.png
cp /cygdrive/c/ProgramData/ServerCare/data/picons/Rai_2.png /cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/Rai_2_+2HD.png
cp /cygdrive/c/ProgramData/ServerCare/data/picons/Rai_2.png /cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/Rai_2_+1HD.png
我需要用 cygwin 来做,我有一个脚本可以在 ubuntu 下做,但是用 cygwin 不工作。这是脚本:
#!/bin/bash
#colori
RED='3[0;31m'
GREEN='3[0;32m'
NC='3[0m'
if [ $# -ne 4 ]
then
echo -e "${RED}ERRORE${NC}, inserire [=13=] filein fileout pathlogo_from pathlogo_to"
echo -e "${RED}Ricorda${NC} le enstensioni!"
exit 0
fi
if [ -f ]
then
echo -n -e "File esistente, vuoi ${RED}sovrascrivere${NC}?(Y/n) "
read scelta
if [ $scelta != 'Y' ]
then
exit 0
else
rm
fi
fi
awk '/\<!--begin_channel--\>/{flag=1; next} /\<!--end_channel--\>/{flag=0} flag' > temp
while read line
do
awk "/$line/,/<!--begin_channel-->/ " | grep -v "$line" | grep -v "^<" > tmp
for channel in `cat tmp`
do
channel=`echo $channel | tr ")" "_" | tr "(" "_" | tr ":" "_"`
echo "cp /$line /$channel"
done
done <temp >>
rm temp
rm tmp
echo -e "${GREEN}File creato correttamente${NC}"
我认为错误与这一行有关
awk "/$line/,/<!--begin_channel-->/ " | grep -v "$line" | grep -v "^<" > tmp
到运行它我用命令
{ bash } »./script.sh channels.xml channels.sh /cygdrive/c/ProgramData/ServerCare/data/picons/ /cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/
有人可以帮我修复它或写一个新的吗?
@Tapiocapioca:尝试:您可以根据您的要求将输出输出到文件或脚本中,然后让我们知道。
awk -vlines=$(cat Input_file | wc -l) -vsource="/cygdrive/c/ProgramData/ServerCare/data/picons/" -vtarget="/cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/" '/<!--end_channel/{getline;while([=10=] !~ /<!--begin_channel/){print "cp " source SOURCE OFS target [=10=];if(NR==lines){exit};getline}} /<!--begin_channel/{getline;SOURCE=[=10=];next}' Input_file
NON-one线性解的形式也如下:
awk -vlines=$(cat Input_file | wc -l) -vsource="/cygdrive/c/ProgramData/ServerCare/data/picons/" -vtarget="/cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/" '
/<!--end_channel/{
getline;
while([=11=] !~ /<!--begin_channel/){
print "cp " source SOURCE OFS target [=11=];
if(NR==lines){
exit
};
getline
}
}
/<!--begin_channel/{
getline;
SOURCE=[=11=];
next
}
' Input_file
虽然我不喜欢蛮力,但这里有一些选择:
awk -vsource="/cygdrive/c/ProgramData/ServerCare/data/picons/"
-vtarget="/cygdrive/c/ProgramData/ServerCare/data/picons/duplicati/"
'/begin_channel/{getline src;gsub(/ /,"_",src)}
/end_channel/{for(i=1;i<3;i++){
getline dest;gsub(/ /,"_",dest);
print "cp",source src,target dest}}' xml_file
上面的好处是,一旦您对输出正确感到满意,您只需在打印和 "cp" 之间放置一个竖线 (|),它就会将输出传送到shell 并进行复制,或者如果您出于某种原因确实需要制作中间脚本,请将管道放在外面并简单地将 awk 重定向到 channels.sh
这里还有一个 bash 替代方案:
xml=""
script=""
src_path=""
dest_path="${src_path}duplicati/"
get_src=0
get_dest=0
while read -r line
do
if [[ "$line" =~ begin_channel ]]
then
get_src=1
get_dest=0
elif [[ "$line" =~ end_channel ]]
then
get_dest=1
get_src=0
else
(( get_src == 1 )) && src="${src_path}${line// /_}"
if (( get_dest == 1 ))
then
dest="${dest_path}${line// /_}"
echo "cp $src $dest"
fi
fi
done<"$xml">"$script"