MANIFEST.MF文件对Import-Package/Export-Package重排列
众所周知,MANIFEST.MF文件中的空格开头的行是相当于拼接在上一行末尾的。很多又长又乱的Import-Package或者Export-Package,有时候想要搜索某个package却可能被换行截断而搜不到。
这时候咱们可以对它进行格式化重新排列,同时又不影响它的正常运行。再排个序方便查找。
排列前 vs 排列后
附上干货 !!!
(脚本方式,对于长一点的package慢的一批,待优化;可对jar文件直接执行,免解压读取META-INF/MANIFEST.MF)
#!/bin/bash # MANIFEST.MF文件对Import-Package/Export-Package重排列
function main() {
echo $ | egrep ".jar$|.zip$" &>/dev/null
if [ $? -eq ];then
MANIFEST=$(unzip -p $ META-INF/MANIFEST.MF)
[ $? -ne ] && echo ${MANIFEST} && exit
else
MANIFEST=$(cat $)
fi
isWindowsDoc="false"
# 判断文件格式是windows还是unix
[ "" != "$(echo "$MANIFEST" | sed -n ":a;N;/\r\n/p;ba")" ] && isWindowsDoc="true"
MANIFEST=$(echo "$MANIFEST" | dos2unix) # 空格开头的行,合并到一行
MANIFEST=$(echo "$MANIFEST" | sed ":a;N;s/\n //g;ba") importPackage=$(echo "${MANIFEST}" | egrep "^Import-Package:" | sed 's/^Import-Package: *//g' | sed 's/ //g')
exportPackage=$(echo "${MANIFEST}" | egrep "^Export-Package:" | sed 's/^Export-Package: *//g' | sed 's/ //g') output=$(echo "${MANIFEST}")
# 引号外的逗号转为特殊分隔符
if [ "" != "${importPackage}" ];then
importPackage=$(dealStrByPython ${importPackage})
importPackage="Import-Package: \n${importPackage}"
len=${#importPackage}
importPackage=$(echo -e "${importPackage:0:$((len-1))}") # 去掉最后一个字符
oneLineImport=$(echo "${importPackage}" | sed ":a;N;s/\n/#/g;ba") # sed命令不能一行换多行,将换行符转为#号变成一行,替换后#号再转回换行符
output=$(echo "${output}" | sed 's/^Import-Package:.*/'"${oneLineImport}"'/g' | sed "s/#/\n/g")
fi
if [ "" != "${exportPackage}" ];then
exportPackage=$(dealStrByPython ${exportPackage})
exportPackage="Export-Package: \n${exportPackage}"
len=${#exportPackage}
exportPackage=$(echo -e "${exportPackage:0:$((len-1))}")
oneLineExport=$(echo "${exportPackage}" | sed ":a;N;s/\n/#/g;ba")
output=$(echo "${output}" | sed 's/^Export-Package:.*/'"${oneLineExport}"'/g' | sed "s/#/\n/g")
fi if [ "true" == "${isWindowsDoc}" ];then
echo "${output}" | unix2dos
else
echo "${output}"
fi
} #按逗号分隔字符串,并忽略双引号中的逗号
#逐个字符遍历
#效率贼慢
function dealStr() {
str=$
newStr=""
isOpenQuotes="false"
splitChar="#"
# 遍历字符串的字符
for((i=; i<${#str}; i++))
do
char=${str:$i:}
if [ "$char" == '"' ];then
if [ "$isOpenQuotes" == "false" ];then
isOpenQuotes="true"
else
isOpenQuotes="false"
fi
fi
[ "$char" == "," ] && [ "$isOpenQuotes" == "false" ] && char=${splitChar}
newStr=${newStr}${char}
done
# 按特殊分隔符分割、排序
echo "${newStr}" | awk -F '#' '{for(n=1;n<=NF;n++) print " "$n","}' | sort
} #按逗号分隔字符串,并忽略双引号中的逗号
#遍历字符串中的双引号和逗号
#效率快了一点点
function dealStrTest() {
str=$
newStr=""
isOpenQuotes="false"
splitChar="#" while true
do
indexOfQuotes=`expr index $str '"'`
indexOfComma=`expr index $str ','`
# 处理引号
if [ $indexOfQuotes -gt ] && [ $indexOfComma -gt ] && [ $indexOfQuotes -lt $indexOfComma ];then
if [ "$isOpenQuotes" == "false" ];then
isOpenQuotes="true"
else
isOpenQuotes="false"
fi
newStr=${newStr}${str::$indexOfQuotes}
str=${str:$indexOfQuotes}
# 处理逗号
elif [ $indexOfQuotes -gt ] && [ $indexOfComma -gt ] && [ $indexOfComma -lt $indexOfQuotes ] || [ $indexOfQuotes -eq ] && [ $indexOfComma -gt ];then
[ "$isOpenQuotes" == "false" ] && newStr=${newStr}${str::$indexOfComma-}${splitChar}
[ "$isOpenQuotes" != "false" ] && newStr=${newStr}${str::$indexOfComma}
str=${str:$indexOfComma}
# 逗号没了
elif [ $indexOfComma -eq ];then
newStr=${newStr}${str}
break
else
break
fi
done
# 按特殊分隔符分割、排序
echo "${newStr}" | awk -F '#' '{for(n=1;n<=NF;n++) print " "$n","}' | sort
} #按逗号分隔字符串,并忽略双引号中的逗号
#使用python逐个字符遍历
#效率更快了
function dealStrByPython() {
str=$
newStr=`python -c "
str='$str'
isOpenQuotes=False
splitChar='#'
chArr=[]
for ch in str.replace(' ',''):
if ch == '\"' :
isOpenQuotes = bool(-isOpenQuotes)
if ch == ',' and isOpenQuotes == False :
chArr.append(splitChar)
else :
chArr.append(ch)
print(''.join(chArr))
"`
# 按特殊分隔符分割、排序
echo "${newStr}" | awk -F '#' '{for(n=1;n<=NF;n++) print " "$n","}' | sort
} main $@
(java方式)
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties; public class ManifestFormatter { private final static String IMPORT_PACKAGE = "Import-Package";
private final static String EXPORT_PACKAGE = "Export-Package";
private final static char SEPARATOR = '#'; public static void main(String[] args) {
File mf = new File(args[0]);
File formatMf = new File(mf.getParentFile(), "MANIFEST.MF.FORMAT");
if (!mf.exists()) {
System.out.println(mf.getAbsolutePath() + " is format failed: " + mf.getAbsolutePath() + " is not exits");
System.exit(2);
}
try (BufferedReader br = new BufferedReader(new FileReader(mf)); BufferedWriter bw = new BufferedWriter(new FileWriter(formatMf));) {
StringBuilder fileToString = new StringBuilder();
char[] chars = new char[1024];
int len;
while ((len = br.read(chars, 0, chars.length)) != -1) {
fileToString.append(new String(chars, 0, len));
} // 转换MANIFEST.MF文件中的属性为单行模式,并保持原来的文档格式
String lineSeparator = fileToString.indexOf("\r\n") != -1 ? "\r\n" : "\n";
String formatStr = fileToString.toString().replaceAll(lineSeparator + " ", "");
ByteArrayInputStream bi = new ByteArrayInputStream(formatStr.getBytes());
Properties properties = new Properties();
properties.load(bi); // 回写MANIFEST.MF文件,重新写入Import-Package与Export-Package
String importPackageStr = properties.getProperty(IMPORT_PACKAGE);
if (importPackageStr != null && importPackageStr.length() > 0) {
List<String> importPackageList = getPackageList(importPackageStr);
String newImportPackageStr = createNewPackage(importPackageList, IMPORT_PACKAGE, lineSeparator);
formatStr = formatStr.replaceAll("Import-Package:.*" + lineSeparator, newImportPackageStr);
}
String exportPackageStr = properties.getProperty(EXPORT_PACKAGE);
if (exportPackageStr != null && exportPackageStr.length() > 0) {
List<String> exportPackageList = getPackageList(exportPackageStr);
String newExportPackageStr = createNewPackage(exportPackageList, EXPORT_PACKAGE, lineSeparator);
formatStr = formatStr.replaceAll("Export-Package:.*" + lineSeparator, newExportPackageStr);
}
bw.write(formatStr);
} catch (IOException e) {
System.out.println(mf.getAbsolutePath() + " is format failed: " + e.getMessage());
e.printStackTrace();
System.exit(1);
}
System.out.println(mf.getAbsolutePath() + " is format successed");
} /**
* 重新创建Import-Package与Export-Package
*
* @param packageList
* @param packageType
* @param lineSeparator
* @return
*/
private static String createNewPackage(List<String> packageList, String packageType, String lineSeparator) {
StringBuilder newPackageString = new StringBuilder(packageType).append(":").append(lineSeparator);
int size = packageList.size();
for (int i = 0; i < size; i++) {
newPackageString.append(" ");
newPackageString.append(packageList.get(i));
if (i < size - 1) {
newPackageString.append(",");
}
newPackageString.append(lineSeparator);
}
return newPackageString.toString();
} /**
* 单行的Import-Package或Export-Package,转化为list数组
*
* @param packageStr 单行的Import-Package或Export-Package
* @param packageType "Import-Package"或"Export-Package"
* @return
*/
private static List<String> getPackageList(String packageStr) {
boolean isOpenQuotes = false;
char[] chArr = packageStr.replaceAll(" ", "").toCharArray();
int len = chArr.length;
// 双引号外面的逗号,转为分隔符
for (int i = 0; i < len; i++) {
if (chArr[i] == '"') {
isOpenQuotes = !isOpenQuotes;
}
if (chArr[i] == ',' && !isOpenQuotes) {
chArr[i] = SEPARATOR;
}
}
List<String> packageList = Arrays.asList(new String(chArr).split(SEPARATOR + ""));
Collections.sort(packageList);
return packageList;
} }
MANIFEST.MF文件对Import-Package/Export-Package重排列的更多相关文章
- 关于java中的MANIFEST.MF 文件内容
打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息.可以简化Java应用程 ...
- Jar文件 META-INF/MANIFEST.MF文件详解
打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息,下面将详细介绍MANI ...
- meta-inf文件夹以及MANIFEST.MF文件的作用
meta-inf相当于一个信息包,目录中的文件和目录获得Java 2平台的认可与解释,用来配置应用程序.扩展程序.类加载器和服务 manifest.mf文件,在用jar打包时自动生成的. META-I ...
- MANIFEST.MF文件Class-Path:节点需要引入的jar太多解决方案
每行开头结尾都要有一个空格(半角的) 例子如下: Manifest-Version: 1.0 Class-Path: lib/mongo-java-driver-2.11.4.jar lib/guav ...
- JAR包中的MANIFEST.MF文件详解以及编写规范
参考百度百科的解释如下: http://baike.baidu.com/item/MANIFEST.MF MANIFEST.MF:这个 manifest 文件定义了与扩展和包相关的数据.单词“mani ...
- MANIFEST.MF 文件内容完全详解(转)
打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个MANIFEST.MF,这个文件描述了该Jar文件的很多信息,下面将详细介绍MANI ...
- MANIFEST.MF Error: No available bundle exports package
Issue: When you imported some 3rd jars and compiled MANIFEST.MF, you may got following compling erro ...
- jar包的MANIFEST.MF文件
打包可执行jar包时,MANIFEST.MF总是个让人头疼的东西,经常出现这种那种问题. 一个例子: ================================================= ...
- JAR包结构,META-INF/MANIFEST.MF文件详细说明[全部属性][打包][JDK]
转载请注:[https://www.cnblogs.com/applerosa/p/9736729.html] 常见的属性 jar文件的用途 压缩的和未压缩的 jar工具 可执行的JAR 1.创建可执 ...
随机推荐
- 修改Ubuntu系统的用户名和主机名
1.前言 当我们拿到别人拷贝的系统时,往往需要修改拷贝系统的密码.用户名和主机名,本文简单介绍在Ubuntu下如何进行相关配置文件的修改. 2.如何修改 (1)修改root的密码 运行下面的命令对对r ...
- Linux手动安装新版本Python教程(CentOS)
一.说明 1.1 linux为什么不升级python版本 2008年python3就发布了,到2020年1月1日python2.7就停止更新了,为什么主流的linux迟迟不去除python2自带pyt ...
- 029 ElasticSearch----全文检索技术04---基础知识详解02-查询
1.查询 (1)基本查询 基本语法: GET /索引库名/_search { "query":{ "查询类型":{ "查询条件":" ...
- linux 重启jmeter服务
#!/bin/bash #jmeter kill and start echo -e '\033[32m--------Jmeter---------------\033[0m' echo " ...
- ElasticSearch 线程池类型分析之 ExecutorScalingQueue
ElasticSearch 线程池类型分析之 ExecutorScalingQueue 在ElasticSearch 线程池类型分析之SizeBlockingQueue这篇文章中分析了ES的fixed ...
- C++ 01 基础知识点
1.为某一特定的问题而设计的指令序列称为:程序 2.‘32位微型计算机’中的32位指的是:机器的字长 3.存储设备中,存取速度最快的是:Cache 4.指令的操作码表示的是:作何操作 5.一条指令由哪 ...
- ubuntu18 docker中部署ELK
ELK是ElasticSearch.Logstash.Kibana的简称,一般用于日志系统,从日志收集,日志转储,日志展示等入手,用以提供简洁高效的日志处理机制. 鉴于没有额外的机器,这里就用dock ...
- 【在 Nervos CKB 上做开发】Nervos CKB 脚本编程简介[5]:调试 debug
作者:Xuejie 原文链接:https://xuejie.space/2019_10_18_introduction_to_ckb_script_programming_debugging/ Ner ...
- MQTTv5.0 ---AUTH – 认证交换
AUTH报文被从客户端发送给服务端,或从服务端发送给客户端,作为扩展认证交换的一部分,比如质询/ 响应认证.如果CONNECT报文不包含相同的认证方法,则客户端或服务端发送AUTH报文将造成协议错 误 ...
- SQL Server中VARCHAR(MAX)和NVARCHAR(MAX)使用时要注意的问题(转载)
在Microsoft SQLServer2005及以上的版本中,对于varchar(n).nvarchar(n)和varbinary(n)有了max的扩展.可以使用如:varchar(max).nva ...