Procesando paquetes (1)

AWKK book coverPensé que estaba algo anquilosado en el uso del AWK, pues desde hacía tiempo que no lo usaba. Pero, como dice el dicho “lo que bien se aprende, jamás se olvida“, he visto que aún me acuerdo de sus particularidades.

Revisando la instalación de algunas cosas en mi vieja MacBook negra con OS X 10.7 para su eliminación, y al no haber un script ni programa de desinstalación, debí abrir el paquete de instalación y revisar sus manifiestos para saber qué es lo que habían traído el o los paquetes de software instalados. Después de montar la imagen de disco, en este caso de las Command Line Tools de XCode, procedí a expandir el paquete con

$ pkgutil --expand 'Command Line Tools.mpkg' $HOME/Downloads/metapackage

La extracción creo un directorio y dentro de éste se encontraba el archivo Distribution.

Al revisar el contenido del manifiesto de distribución, este resultó algo largo y decidí que me sería más informativo poder ver sólo los nombres de los dominios, admás de que por cada uno de éstos habría que hacer algunas cosas más. Claro, una opción sería anotar cada uno de los nombres de los diccionarios para después irlos usando según se fueran necesitando pero, si por cada dominio habría que hacer más de una cosa y además uno quiere estar seguro de no dejar alguno olvidado, no hay nada como automatizar el asunto. Así, el archivo a procesar era:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<installer-gui-script minSpecVersion="1">
    <title>TITLE</title>
<options hostArchitectures="x86_64,i386"/>
    <license file="License.rtf" sla="EA0609"/>
    <welcome file="Welcome.rtf"/>
    <background file="background.tiff" scaling="proportional" alignment="topleft"/>
<options allow-external-scripts="no" customize="never" rootVolumeOnly="true"/>
    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%0A%20%20%20%20var%20majorOSVersion%20%3D%20'10.7'%3B%0A%20%20%20%20var%20lessThanOSVersion%20%3D%20'10.8'%3B%0A%0A%20%20%20%20function%20installationCheck()%20%7B%0A%20%20%20%20%20%20%20%20%2F%2F%20Must%20be%20equal%20to%20majorOSVersion%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(system.compareVersions(system.version.ProductVersion%2C%20majorOSVersion)%20%26lt%3B%200%20%7C%7C%20system.compareVersions(system.version.ProductVersion%2C%20lessThanOSVersion)%20%3E%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20my.result.title%20%3D%20system.localizedStringWithFormat('BAD_OS_VERS_TITLE'%2C%20majorOSVersion)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20my.result.message%20%3D%20system.localizedStringWithFormat('BAD_OS_VERS'%2C%20majorOSVersion)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20my.result.type%20%3D%20'Fatal'%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20return%20true%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20volumeCheck()%20%7B%0A%20%20%20%20%20%20%20%20if%20(system.env.OS_INSTALL%20%3D%3D%201)%20return%20true%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Must%20have%20an%20OS%20and%20be%20minOSVersion%20or%20greater%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if%20(!system.files.fileExistsAtPath(my.target.mountpoint%20%2B%20%22%2FSystem%2FLibrary%2FCoreServices%2FSystemVersion.plist%22)%0A%20%20%20%20%20%20%20%20%20%20%20%20%7C%7C%20system.compareVersions(my.target.systemVersion.ProductVersion%2C%20majorOSVersion)%20%26lt%3B%200%0A%20%20%20%20%20%20%20%20%20%20%20%20%7C%7C%20system.compareVersions(my.target.systemVersion.ProductVersion%2C%20lessThanOSVersion)%20%3E%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20my.result.type%20%3D%20'Fatal'%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20my.result.message%20%3D%20system.localizedStringWithFormat('BAD_OS_VERS'%2C%20minOSVersion)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20true%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
    <volume-check script="volumeCheck()"/>
    <installation-check script="installationCheck()"/>
    <choices-outline>
        <line choice="UNIXDevelopmentSupport"/>
    </choices-outline>
    <choice id="UNIXDevelopmentSupport" title="TITLE" description="TITLE" enabled="true" start_selected="true" customLocation="/" customLocationAllowAlternateVolumes="YES">
        <pkg-ref id="com.apple.pkg.DevSDK"/>
        <pkg-ref id="com.apple.pkg.X11SDK"/>
        <pkg-ref id="com.apple.pkg.QuickTimeSDK"/>
        <pkg-ref id="com.apple.pkg.OpenGLSDK"/>
        <pkg-ref id="com.apple.pkg.WebKitSDK"/>
        <pkg-ref id="com.apple.pkg.FireWireSDK"/>
        <pkg-ref id="com.apple.pkg.BluetoothSDK"/>
        <pkg-ref id="com.apple.pkg.CoreAudioSDK"/>
        <pkg-ref id="com.apple.pkg.JavaSDK"/>
        <pkg-ref id="com.apple.pkg.clang"/>
        <pkg-ref id="com.apple.pkg.llvm-gcc4.2"/>
        <pkg-ref id="com.apple.pkg.X11Documentation"/>
        <pkg-ref id="com.apple.pkg.DeveloperToolsCLI"/>
    </choice>
    <pkg-ref id="com.apple.pkg.DeveloperToolsCLI" auth="root">file:./Packages/DeveloperToolsCLI.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.X11Documentation" auth="root">file:./Packages/X11Documentation.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.clang" auth="root">file:./Packages/clang.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.llvm-gcc4.2" auth="root">file:./Packages/llvm-gcc4.2.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.DevSDK" auth="root">file:./Packages/DevSDK.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.BluetoothSDK" auth="root">file:./Packages/BluetoothSDK.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.FireWireSDK" auth="root">file:./Packages/FireWireSDK.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.CoreAudioSDK" auth="root">file:./Packages/CoreAudioSDK.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.OpenGLSDK" auth="root">file:./Packages/OpenGLSDK.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.QuickTimeSDK" auth="root">file:./Packages/QuickTimeSDK.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.WebKitSDK" auth="root">file:./Packages/WebKitSDK.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.X11SDK" auth="root">file:./Packages/X11SDK.pkg</pkg-ref>
    <pkg-ref id="com.apple.pkg.JavaSDK" auth="root">file:./Packages/JavaSDK.pkg</pkg-ref>
    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%0A%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
    <license file="License.rtf"/>

        <pkg-ref id='com.apple.pkg.clang' installKBytes='30106' version='4.3.0.0.1.1249367152'/>
        <pkg-ref id='com.apple.pkg.DeveloperToolsCLI' installKBytes='118238' version='4.3.0.0.1.1249367152'/>
        <pkg-ref id='com.apple.pkg.llvm-gcc4.2' installKBytes='32345' version='4.3.0.0.1.1249367152'/>

        <pkg-ref id='com.apple.pkg.clang' installKBytes='30106' version='4.3.0.0.1.1249367152'/>
        <pkg-ref id='com.apple.pkg.DeveloperToolsCLI' installKBytes='118238' version='4.3.0.0.1.1249367152'/>
        <pkg-ref id='com.apple.pkg.llvm-gcc4.2' installKBytes='32345' version='4.3.0.0.1.1249367152'/>

</installer-gui-script>

y lo que se buscaba son aquello nombres del atributo id que aparecen en las etiquetas pkg-ref. Si bien la eliminación del nombre del atributo no era problema, la terminación del atributo sí. En un inicio pensé que la eliminación de ‘ y ” usando gsub sería suficiente pero puede verse que en la primera ocurrencia de estos nombres aparecen además />. Adicionalmente (y no sé si será sólo cosa del BASH, ya que suelo usar el Korn shell y esto siempre lo arreglaba escapando al caracter problematico, pero en esta ocasión no me funcionó) el buscar eliminar " y ' parecían confundir al parser del shell. El asunto se arregló substituyendo en el campo todo aquello que no fuera una letra, número o punto por una épsilon. Cualquier duplicidad que pudiera haber se eliminó usando un arreglo asociativo. El one-liner de AWK finalmente quedó:

$ awk '/pkg-ref/ {for(f=1;f<=NF;f++){if(match($f,"id=")){ gsub(/id=/,"",$f); gsub(/[^A-Za-z.0-9]/,"",$f); c[$f]++}}} END{for( x in c) print x}' metapackage/Distribution

que produce la salida:

com.apple.pkg.CoreAudioSDK
com.apple.pkg.X11SDK
com.apple.pkg.DevSDK
com.apple.pkg.llvmgcc4.2
com.apple.pkg.X11Documentation
com.apple.pkg.JavaSDK
com.apple.pkg.BluetoothSDK
com.apple.pkg.clang
com.apple.pkg.FireWireSDK
com.apple.pkg.OpenGLSDK
com.apple.pkg.WebKitSDK
com.apple.pkg.DeveloperToolsCLI
com.apple.pkg.QuickTimeSDK

Por supuesto, esto fue sólo el primer paso.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios .