我正在尝试获取托管在我服务器上的内容管理系统的版本号。如果版本号存储在一行上,我可以相当简单地做到这一点:
grep -r "\$wp_version = '" /home/
它返回了我想要的标准输出:
/home/$RANDOMDOMAIN/wp-includes/version.php:$wp_version = '3.7.1';
我遇到的问题是当我开始寻找存储在两条或更多条线上的版本号时,比如Joomla!或Magento分别使用以下格式:
的Joomla:
/** @var string Release version. */
public $RELEASE = '3.2';
/** @var string Maintenance version. */
public $DEV_LEVEL = '3';
的Magento:
'major' => '1',
'minor' => '8',
'revision' => '1',
'patch' => '0',
我已经在某种程度上使用以下方法工作了(如果由于某种原因,我正在寻找的其中一个字符串缺少整个命令就会变得无用,因此使用此方法xargs -l3期望在-print)提供的路径上方2行:
find /home/ -type f -name version.php -exec grep " \$RELEASE " '{}' \; -exec grep " \$DEV_LEVEL " '{}' \; -print | xargs -l3 | sed 's/\<var\>\s//g;s/\<public\>\s//g' | awk -F\; '{print $3":"$1""$2}' | sed 's/ $DEV_LEVEL = /./g'
我的输出是这样的:
/home/$RANDOMDOMAIN/version.php:$RELEASE = 3.2.3
/home/$RANDOMDOMAIN/anotherfolder/version.php:$RELEASE = 1.5.0
我还有一个for循环,它将排除任何不包含两个字符串的文件,但是根据它需要筛选的数量,可能比上面的查找一个内容要长得多:
for path in $(grep -rl " \$RELEASE " /home/ 2> /dev/null | xargs grep -rl " \$DEV_LEVEL ")
do
joomlaver="$path"
joomlaver+=$(grep " \$RELEASE " $path)
joomlaver+=$(echo " \$DEV_LEVEL = '$(grep " \$DEV_LEVEL " $path | cut -d\' -f2)';")
echo "$joomlaver" | sed 's/\<var\>\s//g;s/\<public\>\s//g;s/;//g' | awk -F\' '{ print $1""$2"."$4 }' | sed 's/\s\+//g'
unset joomlaver
done
我的输出是这样的:
/home/$RANDOMDOMAIN/version.php$RELEASE=3.2.3
/home/$RANDOMDOMAIN/anotherfolder/version.php$RELEASE=1.5.0
但我必须相信有一种更简单,更短,更优雅的方式。 Bash是首选,或者如果它可以用perl one衬里完成,那也可以。任何和所有的帮助将不胜感激。提前致谢。 (对不起,所有的编辑,但我也试图自己解决这个问题!)
答案 0 :(得分:0)
这是一个perl单行程序,它将从您显示的php文件格式中提取$ RELEASE和$ DEV_LEVEL:
perl -ne '$v=$1 if /\$RELEASE\s*=\s*\047([0-9.]+)\047/; $devlevel=$1 if /\$DEV_LEVEL\s*=\s*\047([0-9.]+)\047/; if (defined $v && defined $devlevel) { print "$ARGV: Release=$v Devlevel=$devlevel\n"; last; }'
-n使perl有效地将整个事物包装在while (<>) { }
循环中。针对两个正则表达式检查每一行。如果它们都匹配,那么它将打印结果并退出。
\ 047用于匹配单引号,否则shell会混淆。
如果找不到匹配项,则不会打印任何内容。否则它打印出这样的东西:
sample.php: Release=3.2 Devlevel=3
您可以将它与find和xargs结合使用来遍历目录结构,可能是这样的:
find . -name "*.php" | xargs perl -ne '$v=$1 if /\$RELEASE\s*=\s*\047([0-9.]+)\047/; $devlevel=$1 if /\$DEV_LEVEL\s*=\s*\047([0-9.]+)\047/; if (defined $v && defined $devlevel) { print "$ARGV: Release=$v Devlevel=$devlevel\n"; last; }'
你可以为你提到的其他文件格式(Magento?)制作一个类似的版本。