I am trying to parse android package list from phone. Sample data is as shown below.
Package [com.google.android.as] (9faf0bc):
userId=10320
pkg=Package{299f845 com.google.android.as}
codePath=/system/priv-app/DevicePersonalizationServices
resourcePath=/system/priv-app/DevicePersonalizationServices
legacyNativeLibraryDir=/system/priv-app/DevicePersonalizationServices/lib
primaryCpuAbi=arm64-v8a
secondaryCpuAbi=null
versionCode=4371429 minSdk=30 targetSdk=30
versionName=R.3.sysimg.oem.325908743
splits=[base]
apkSigningVersion=0
applicationInfo=ApplicationInfo{299f845 com.google.android.as}
flags=[ SYSTEM HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
privateFlags=[ PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION ALLOW_AUDIO_PLAYBACK_CAPTURE PRIVILEGED PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING ]
forceQueryable=false
queriesPackages=[]
dataDir=/data/user/0/com.google.android.as
supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity]
timeStamp=2008-12-31 20:30:00
firstInstallTime=2008-12-31 20:30:00
lastUpdateTime=2008-12-31 20:30:00
signatures=PackageSignatures{f91eb9a version:0, signatures:[], past signatures:[]}
installPermissionsFixed=false
pkgFlags=[ SYSTEM HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP ]
install permissions:
android.permission.MODIFY_AUDIO_ROUTING: granted=true
android.permission.SYSTEM_ALERT_WINDOW: granted=true
<< multiple lines >>
android.permission.READ_DEVICE_CONFIG: granted=true
android.permission.READ_OEM_UNLOCK_STATE: granted=true
User 0: ceDataInode=0 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
gids=[3002, 3003, 3001]
User 150: ceDataInode=0 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
gids=[3002, 3003, 3001]
Package [com.google.android.gm] (a066ccb):
userId=10230
pkg=Package{9e45ca8 com.google.android.gm}
codePath=/system/app/Gmail2
resourcePath=/system/app/Gmail2
legacyNativeLibraryDir=/system/app/Gmail2/lib
primaryCpuAbi=null
secondaryCpuAbi=null
versionCode=62209002 minSdk=21 targetSdk=29
versionName=2020.05.31.316831277.release
splits=[base]
apkSigningVersion=0
applicationInfo=ApplicationInfo{9e45ca8 com.google.android.gm}
flags=[ SYSTEM HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP KILL_AFTER_RESTORE RESTORE_ANY_VERSION ]
privateFlags=[ PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE ALLOW_AUDIO_PLAYBACK_CAPTURE PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE HAS_DOMAIN_URLS PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING ]
forceQueryable=false
queriesIntents=[Intent { act=android.support.customtabs.action.CustomTabsService }, Intent { act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=http://www.example.com/... }, Intent { act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=http://www.example.com/... }, Intent { act=android.support.customtabs.action.CustomTabsService }]
dataDir=/data/user/0/com.google.android.gm
supportsScreens=[small, medium, large, xlarge, resizeable, anyDensity]
usesLibraries:
android.test.base
usesOptionalLibraries:
org.apache.http.legacy
timeStamp=2008-12-31 20:30:00
firstInstallTime=2008-12-31 20:30:00
lastUpdateTime=2008-12-31 20:30:00
signatures=PackageSignatures{c66d3c1 version:0, signatures:[], past signatures:[]}
installPermissionsFixed=false
pkgFlags=[ SYSTEM HAS_CODE ALLOW_CLEAR_USER_DATA ALLOW_BACKUP KILL_AFTER_RESTORE RESTORE_ANY_VERSION ]
declared permissions:
com.google.android.gm.email.permission.READ_ATTACHMENT: prot=signature
com.google.android.gm.email.permission.ACCESS_PROVIDER: prot=signature
<< multiple lines >>
com.android.launcher.permission.INSTALL_SHORTCUT: granted=true
com.google.android.gms.permission.REQUEST_SCREEN_LOCK_COMPLEXITY: granted=true
android.permission.WAKE_LOCK: granted=true
User 0: ceDataInode=0 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
gids=[3003]
User 150: ceDataInode=0 installed=true hidden=false suspended=false distractionFlags=0 stopped=false notLaunched=false enabled=0 instant=false virtual=false
gids=[3003]
To parse data in AWK, I am using the command as under
dumpsys package | awk '/^[ ]*Package \[.*\] (.*)/ { i = index($0, "[") + 1; pkg = substr($0, i, index($0, "]") - i); } /[ ]*versionCode=/ /[ ]*versionName=/ /[ ]*firstInstallTime=/ /[ ]*lastUpdateTime=/ { { print "START PackageName=" pkg $0 " END"; pkg = ""; } }'
Output of the above command is as under
versionCode=4371429 minSdk=30 targetSdk=30 versionName=R.3.sysimg.oem.325908743 firstInstallTime=2008-12-31 20:30:00START PackageName=com.google.android.as lastUpdateTime=2008-12-31 20:30:00 END versionCode=62209002 minSdk=21 targetSdk=29 versionName=2020.05.31.316831277.release firstInstallTime=2008-12-31 20:30:00START PackageName=com.google.android.gm lastUpdateTime=2008-12-31 20:30:00 END
The problem is the order of data output. The expected output should be in order between START and END as being printed. I am not able to get the structured data as desired. Please advise.
EDIT2
To output data for one package on one line, delimited by tabs,
append | paste - - - -
to the awk
command, i.e. one dash for each of
the 4 attributes selected.
paste
has a -d
option to specify a delimiter.
Or you could use my original answer which did that - with attributes in specified order - if you passed -v isheader=""
to awk
.
EDIT
Second attempt, perhaps I misread:
dumpsys package | awk '
/^[ ]*Package \[/ {
pkg = substr($2,2,length($2)-2)
}
/^[ ]*(versionCode|versionName|firstInstallTime|lastUpdateTime)=/ {
print "START PackageName=" pkg $0 " END"
}
'
or, as a one-liner:
dumpsys package | awk '/^[ ]*Package \[/ { pkg = substr($2,2,length($2)-2); } /^[ ]*(versionCode|versionName|firstInstallTime|lastUpdateTime)=/ { print "START PackageName=" pkg $0 " END"; }'
Output:
START PackageName=com.google.android.as versionCode=4371429 minSdk=30 targetSdk=30 END
START PackageName=com.google.android.as versionName=R.3.sysimg.oem.325908743 END
START PackageName=com.google.android.as firstInstallTime=2008-12-31 20:30:00 END
START PackageName=com.google.android.as lastUpdateTime=2008-12-31 20:30:00 END
START PackageName=com.google.android.gm versionCode=62209002 minSdk=21 targetSdk=29 END
START PackageName=com.google.android.gm versionName=2020.05.31.316831277.release END
START PackageName=com.google.android.gm firstInstallTime=2008-12-31 20:30:00 END
START PackageName=com.google.android.gm lastUpdateTime=2008-12-31 20:30:00 END
You were very close but ||
operators were missing between regexes, and pkg
was reset to an empty string in the second awk pattern.
(Original answer follows)
The output you posted is basically a conf file with key-value pairs but repeated for each 'Package' section.
The following awk
script collects the values for attributes given
in the att
variable in an associative array (Val
) and prints the
array as tab-separated values (TSV) in one line per section, in the
specified order.
OFS
is awk
's output field separator. Like the att
and isheader
variables OFS
can be specified on the awk
command line.
It defaults to tab here but can be overridden with ofs="\\n"
or
ofs="|"
for example.
Use with mawk
or gawk
as:
: ${ofs=$(printf '\t')}
dumpsys-command |
awk -v OFS="${ofs}" -v isheader="" -f '/path/to/script' |
while IFS="${ofs}" read -r pkg vcode vname dt1st dtupd
do printf '%s\n' '# -----' \
"Package: ${pkg}" \
"Version code: ${vcode}" \
"Last update: ${dtupd}"
done
BEGIN {
regexSectionStart = "^ *Package "
keyvalsep = "="
if ( !att )
att="pkg versionCode versionName firstInstallTime lastUpdateTime"
split(att, Att, " ")
for ( i in Att )
Idx[Att[i]] = i
if ( isheader )
emitArr(Att)
}
$0 ~ regexSectionStart {
emitArr(Val)
for ( i in Val )
delete Val[i]
next
}
{
key = substr($1, 1, -1+index($1,keyvalsep))
if ( key in Idx )
Val[Idx[key]] = substr($0, 1+index($0,keyvalsep))
}
## Print array in index order, skip if empty
function emitArr(V, i,s) {
for ( i in V ) {
for ( i=1; i<=length(V); i++ )
s = s (i==1 ? "" : OFS) V[i]
print s
return
}
}
END{ emitArr(Val); }
Output from awk
script (isheader="x"
):
pkg versionCode versionName firstInstallTime lastUpdateTime
Package{299f845 com.google.android.as} 4371429 minSdk=30 targetSdk=30 R.3.sysimg.oem.325908743 2008-12-31 20:30:00 2008-12-31 20:30:00
Package{9e45ca8 com.google.android.gm} 62209002 minSdk=21 targetSdk=29 2020.05.31.316831277.release 2008-12-31 20:30:00 2008-12-31 20:30:00
Output from shell script:
# -----
Package: Package{299f845 com.google.android.as}
Version code: 4371429 minSdk=30 targetSdk=30
Last update: 2008-12-31 20:30:00
# -----
Package: Package{9e45ca8 com.google.android.gm}
Version code: 62209002 minSdk=21 targetSdk=29
Last update: 2008-12-31 20:30:00