在我的Packages文件中,我有多个包。如果字符串在里面,我可以检查文件,如果是,我想获得该文件的版本。
Package: depictiontest
Version: 1.0
Filename: ./debs/com.icr8zy.depictiontest.deb
Size: 810
Description: Do not install. Testing Depiction.
Name: Depiction Test
所以上面是包的许多类似外观信息的一部分。每次我检测到包是否存在我想获得版本。有什么可能吗?
不过,这是我用来检查文件是否存在的原因。if grep -q "$filename" /location/Packages; then
#file exists
#get file version <-- stuck here
else
#file does not exists
fi
编辑: 对不起,也许我不清楚解释自己,我已经有了包的名称,并希望只提取该包的版本。我不需要循环来获取所有的名称和版本。希望这清除它...... :)
答案 0 :(得分:2)
如何首先提取文件名?为什么不解析整个文件,然后过滤掉不存在的文件名。
awk '/^Package:/{p=$2}
/^Version:/{v=$2}
/^Filename:/{f=$2}
/^$/{print p, v, f}' Packages |
while read p v f; do
test -e "$f" || continue
echo "$p $v"
done
这对于例如带有空格的文件名,但包文件没有带空格的文件名。 (你的示例文件名是非标准的,但我们假设它并不比这更差。)
您希望确保在包的末尾有一个空行,或者强制它{ sed '$/^$/d' Packages; echo; } | awk ...
编辑:这假设格式相当合格的Packages
文件,记录之间有一个空行。如果记录缺少其中一个字段,则输出将重复上一条记录中的值 - 这是令人讨厌的。如果有多个相邻的空行,它将输出相同的包两次。等等。如果你想要健壮的解析,我会切换到Perl或Python,或者使用标准的Debian工具(我肯定必须有一个)。
答案 1 :(得分:1)
使用grep,您可以在关键字之前或之后选择一定数量的行。
egrep -A1 "^Package: depictiontest" /path/to/file
在匹配后,会产生1个额外的行。
egrep -B1 "^Filename: .*depictiontest.*" /path/to/file
在匹配之前会产生额外的一行。
egrep "^(Package|Version): " "^Package: depictiontest" /path/to/file
只会导致包和版本行,所以依赖于它们的顺序正确,找出哪个版本属于哪个包。
答案 2 :(得分:0)
如果“Version:...”行在“Filename:...”行之前总是正好一行,那么您可以尝试这样的事情:
line_number=$(grep -n "$filename" /location/Packages | head -1 | cut -d: -f1)
if (( $line_number > 0 )); then
#file exists
version=$(head -n $(( $line_number - 1 )) /location/Packages | tail -1 | cut -d' ' -f2)
else
#file doesn't exist
fi
答案 3 :(得分:0)
如果订单相同,那么您可以解析整个文件并将值输入到数组中 -
awk -F": " '
/^Package/{p=$2;getline;v=$2;getline;f=$2;ary[p"\n"v"\n"f"\n"]}
END{for (x in ary) print x}' file
[jaypal:~/Temp] cat file
Package: depictiontest
Version: 1.0
Filename: ./debs/com.icr8zy.depictiontest.deb
Size: 810
Description: Do not install. Testing Depiction.
Name: Depiction2fdf Test
Package: depi444ctiontest
Version: 1.05
Filename: ./debs/coffm.icr8zy.depictiontest.deb
Size: 810
Description: Do not install. Testing Depiction.
Name: Depiction Test
Package: depic33tiontest
Version: 1.01
Filename: ./d3ebs/com.icr8zy.depictiontest.deb
Size: 810
Description: Do not install. Testing Depiction.
Name: Depiction Test
[jaypal:~/Temp] awk -F": " '/^Package/{p=$2;getline;v=$2;getline;f=$2;ary[p"\n"v"\n"f"\n"]}END{for (x in ary) print x}' file
depi444ctiontest
1.05
./debs/coffm.icr8zy.depictiontest.deb
depic33tiontest
1.01
./d3ebs/com.icr8zy.depictiontest.deb
depictiontest
1.0
./debs/com.icr8zy.depictiontest.deb
答案 4 :(得分:0)
我能想到的最简单的awk
实现:
$ awk -F':' -v package='depictiontest' '
$1 == "Package" {
trimmed_package_name = gensub(/^ */, "", "", $2)
found_package = (trimmed_package_name == package)
}
found_package && $1 == "Version" {
trimmed_version_number = gensub(/^ */, "", "", $2)
print trimmed_version_number
}
' Packages
1.0
这将逐行处理文件(Packages
),如果行以'Package'开头,则设置found_package
标志,并在字段分隔符后面设置值-F
) ,:
(和任何空格)是传递给package
变量(-v
)的值。然后,如果设置了标志,我们找到以“Version”字段开头的行,我们在字段分隔符之后打印该值(修剪前导空格)。如果找到另一个“包”字段且名称不是我们要查找的字段,则重置该标志并且不会打印后续版本号。