Sed: Excluindo todo o conteúdo que corresponde a um padrão

1

Eu tenho alguns arquivos plist no Mac OS X que eu gostaria de encolher. Eles têm muito <dict> com <key> e valores. Uma dessas chaves é uma miniatura que possui um valor <data> com binário codificado base64 (eu acho). Eu gostaria de remover essa chave e valor.

Eu estava pensando que isso poderia ser feito por sed, mas eu realmente não sei como usá-lo e parece que o sed só funciona linha a linha?

De qualquer maneira eu estava esperando que alguém pudesse me ajudar. No arquivo, gostaria de excluir tudo o que corresponde ao seguinte padrão ou algo próximo a ele:

<key>Thumbnail<\/key>[^<]*<\/data>

No arquivo, é assim:

            // Other keys and values

            <key>Thumbnail</key>
            <data>
            TU0AKgAAOEi25Pqx3/ip2fak0vOdzPCVxu2RweuPv+mLu+mIt+aGtuaEtOSB

            ...

            dCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA=
            </data>

            // Other keys and values

Alguém sabe como eu poderia fazer isso? Além disso, se houver ferramentas melhores que eu possa usar no terminal para fazer isso, eu gostaria de saber sobre isso também:)

    
por Svish 07.04.2010 / 16:04

4 respostas

4

Existem dois utilitários disponíveis na linha de comando dedicada especificamente ao trabalho com arquivos de lista de preferências: defaults (em /usr/bin ) e PlistBuddy in ( /usr/libexec ).

Ainda usando sed :

sed permite uma exclusão de várias linhas usando o sinal D em vez de d .

por exemplo. sed -e '/<key>Thumbnail<\/key>/, /<\/data>/D' < /PATH/TO/FILE.txt remove todas as instâncias da Miniatura da chave e seus dados associados.

Usando defaults :

defaults delete /PATH/TO/PLIST "Thumbnail" . Não inclua a extensão .plist como parte do caminho. Além disso, isso funcionará somente nos itens de nível raiz em .plist , portanto, se a tecla Miniatura estiver dentro de outra matriz ou dict, ela não funcionará.

Usando PlistBuddy :

/usr/libexec/PlistBuddy -c "Delete :Thumbnail" /PATH/TO/PLIST.plist . Se a tecla Miniatura estiver aninhada, você pode anexar o caminho antes, se souber. por exemplo. PlistBuddy -c "Delete :User:Thumbnail" se a entrada de Miniatura estava em um dicionário do usuário.

    
por 07.04.2010 / 18:25
0
O XMLStarlet é uma excelente ferramenta de linha de comando para manipular XML. Os principais problemas são: 1) é uma ferramenta complexa muito (já que faz trabalhos muito complexos), e 2) você provavelmente terá que construí-la para o OS X.

    
por 07.04.2010 / 17:20
0

use o awk, não o sed

$ cat file
asdkf
asdklf
            // Other keys and values

            <key>Thumbnail</key>
            <data>
            TU0AKgAAOEi25Pqx3/ip2fak0vOdzPCVxu2RweuPv+mLu+mIt+aGtuaEtOSB

            ...

            dCBBcHBsZSBDb21wdXRlciwgSW5jLiwgMjAwNQAAAAA=
            </data>

            // Other keys and values

ksdf

$ awk 'BEGIN{RS="</data>"} /<key>/{ gsub("<key>.*</key>|<data>.*","") }1' file
asdkf
asdklf
            // Other keys and values





            // Other keys and values

ksdf

a declaração diz, use </data> como separador de registro e substitua as tags <key> e <data> por nada, quando <key> for encontrado no registro

    
por 09.04.2010 / 04:50
0

Pode ser possível fazer isso com sed, mas seria difícil. Perl poderia fazer isso mais facilmente. As entranhas do script perl seriam:

undef $/; # This allows reading in of all lines in one swoop

$contents = <>; # Read in contents of file (specified on command line)

$contents = s{<key>Thumbnail</key>.*?</data>}{}s;

print $contents;

Se você tivesse o acima em um script em Perl chamado change.plx e tivesse seus dados em um arquivo chamado keyfile, poderia consertar o arquivo fazendo isso:

$ perl change.plx keyfile > /tmp/$$ && cat /tmp/$$ > keyfile && rm /tmp/$$

Claro, certifique-se de ter um backup de qualquer arquivo para o qual você faça isso. É possível fazer todo esse trabalho em múltiplos arquivos com um único programa perl de uma linha na linha de comando assim:

$ perl -p0777i -e 's{<key>Thumbnail</key>.*?</data>}{}s;' file file file ...

Marnix

    
por 07.04.2010 / 17:08