我必须创建一个bash脚本,用于处理来自不同文件的多个匹配项。这些文件都包含在目录中,具有相同的扩展名(.desktop)。这是一个例子:
[Desktop Entry]
Icon=text-x-c++src
Name=button.cpp
Type=Link
URL[$e]=file://$HOME/Configs/button.cpp
X-KDE-LastOpenedWith=kate
匹配是URL,LastOpenedWith,Name和Icon。它们中的每一个都必须存储到一个不同的变量(例如$ Name,$ URL等)中,这些变量将被打印到xml文件中,相应于这个sintax:
<action label="$Name" icon="$Icon" exec="$LastOpenedWith $URL"/>
为所有.desktop文件创建单个条目。
我真的不知道怎么做,因为我是bash脚本的初学者,欢迎任何提示:)
答案 0 :(得分:2)
您可以在一个awk脚本中执行此操作:
parse.awk:
#!/usr/bin/awk -f
BEGIN {
FS="="
}
/^Name/ {
name=$2
}
/^Icon/ {
icon=$2
}
/^URL/ {
url=$2
}
/LastOpenedWith/ {
lastopenedwith=$2
printf("<action label=\"%s\" icon=\"%s\" exec=\"%s %s\"/>\n", name, icon, lastopenedwith, url)
}
致电
./parse.awk *.desktop
这个脚本的工作假设X-KDE-LastOpenedWith出现在每个* .desktop文件的最后一行......
答案 1 :(得分:1)
既然你说你是Bash的新手,那么这是一个解决方案:使用Python。它是一种更好的编程语言,它附带了一个用于解析配置文件的库,就像你正在处理的那样:http://docs.python.org/library/configparser.html。它也可以轻松编写XML,与Bash不同,您不必学习第二语言sed
来完成工作 - 您可以使用Python完成所有工作。
编辑:这是一个Python程序:
#!/usr/bin/env python
import ConfigParser
import sys
for filename in sys.argv[1:]: # each argument except the program name itself
parser = ConfigParser.RawConfigParser()
parser.read(filename)
name = parser.get('Desktop Entry', 'Name')
icon = parser.get('Desktop Entry', 'Icon')
app = parser.get('Desktop Entry', 'X-KDE-LastOpenedWith')
url = parser.get('Desktop Entry', 'URL[$e]')
print '<action label="{}" icon="{}" exec="{} {}"/>'.format(name, icon, app, url)
既然你说调用程序需要一个shell脚本,我在顶部包含了“shebang line”,所以它不应该知道它们的区别(你的shell会自动调用Python)。
答案 2 :(得分:1)
这样的事可能有用:
echo -e "<menu>\n<submenu>" > output.xml
for f in *.desktop; do
Icon=$(awk -F= '/Icon/{print $2}' "$f")
Name=$(awk -F= '/Name/{print $2}' "$f")
URL=$(awk -F= '/URL/{print $2}' "$f")
LastOpenedWith=$(awk -F= '/X-KDE-LastOpenedWith/{print $2}' "$f")
echo "<action label=\"$Name\" icon=\"$Icon\" exec=\"$LastOpenedWith $URL\"/>"
done >> output.xml
echo -e "</submenu>\n</menu>" >> output.xml
使用Config::IniFiles的Perl解决方案可能如下所示:
#!/usr/bin/env perl
use strict;
use warnings;
use Config::IniFiles;
open XML, ">/path/to/output.xml" or die $!;
print XML "<menu>\n<submenu>\n";
foreach my $file (</path/to/*.desktop>) {
my $ini = Config::IniFiles->new( -file => "$file" );
printf XML "<action label='%s' icon='%s' exec='%s %s'/>\n",
$ini->val('Desktop Entry', 'Name'),
$ini->val('Desktop Entry', 'Icon'),
$ini->val('Desktop Entry', 'X-KDE-LastOpenedWith'),
$ini->val('Desktop Entry', 'URL[$e]')
}
print XML "</submenu>\n</menu>\n";
close XML;
答案 3 :(得分:0)
#This functions gets a field from a ".desktop" file
get_variable()
{
FILE=$1
FIELD=$2
#grep the lines that starts with the fields and cuts them after '=' char
grep -m 1 -e "^$FIELD" "$FILE" | cut -f 2 -d"="
}
#gets all the .desktop files in the current folder
#gets the specified fields from them
for file in *.desktop; do
name=get_variable "$file" "Name"
type=get_variable "$file" "Type"
icon=get_variable "$file" "Icon"
url=get_variable "$file" "URL"
last=get_variable "$file" "X-KDE-LastOpenedWith"
#echo the XML file
echo "<action label=\"$name\" icon=\"$icon\" exec=\"$last $url\"/> "
done