【问题标题】:Print string with variables in AWK在 AWK 中打印带有变量的字符串
【发布时间】:2021-08-05 00:05:12
【问题描述】:

我正在尝试从手机解析 android 包列表。 样本数据如下图。

  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]

为了在 AWK 中解析数据,我使用如下命令

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 = ""; } }'

上述命令的输出如下

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

问题是数据输出的顺序。预期的输出应该在 START 和 END 之间按顺序打印。我无法根据需要获取结构化数据。 请指教。

【问题讨论】:

  • 我建议您发布您的预期结果。人们更容易回答。

标签: android parsing awk adb dumpsys


【解决方案1】:

EDIT2

在一行上输出一个包的数据,由制表符分隔, 将| paste - - - - 附加到awk 命令,即每个破折号 选择的 4 个属性。 paste 有一个-d 选项来指定分隔符。

或者你可以使用我的原始答案 - 使用指定顺序的属性 - 如果你将 -v isheader="" 传递给 awk

编辑

第二次尝试,可能是我看错了:

dumpsys package | awk '
/^[ ]*Package \[/ { 
    pkg = substr($2,2,length($2)-2)
}
/^[ ]*(versionCode|versionName|firstInstallTime|lastUpdateTime)=/ { 
    print "START PackageName=" pkg $0 " END"
}
'

或者,作为一个单行:

dumpsys package | awk '/^[ ]*Package \[/ { pkg = substr($2,2,length($2)-2); } /^[ ]*(versionCode|versionName|firstInstallTime|lastUpdateTime)=/ { print "START PackageName=" pkg $0 " END"; }'

输出:

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

您非常接近,但正则表达式之间缺少 || 运算符,并且 pkg 在第二个 awk 模式中被重置为空字符串。


(原答案如下)

您发布的输出基本上是一个带有键值的conf文件 对,但对每个“包”部分重复。

以下awk 脚本收集给定属性的值 在关联数组 (Val) 的 att 变量中并打印 数组作为制表符分隔值 (TSV) 在每节一行中,在 指定顺序。

OFSawk 的输出字段分隔符。喜欢attisheader 变量OFS 可以在awk 命令行中指定。 它默认为选项卡,但可以用ofs="\\n" 或覆盖 以ofs="|" 为例。

mawkgawk 一起使用:

: ${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); }

awk 脚本 (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

shell 脚本的输出:

# -----
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

【讨论】:

  • 嗨@urcodebetterznow,谢谢你的脚本,但我需要一个单行解决方案,因为我必须将它与命令一起传递。我正在尝试将上述解决方案集成到 Windows 中,因此我必须仅在远程设备上执行命令。
  • @AnkitSharma:查看我的更新答案;我认为这可以满足您的需求。
  • 嗨@urcodebetterznow,几乎是我需要的,但我们得到了2个包的8行输出。预计只有 2 行。我正在尝试后期操作。非常感谢您的支持
  • @AnkitSharma:我的答案现已更新,建议使用 paste 命令。
  • 再次感谢,@urcodebetterznow,如果项目完成,我一定会提到你。
猜你喜欢
  • 2016-01-02
  • 1970-01-01
  • 2019-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多