My favorites | Sign in
Project Home Downloads Wiki Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# ----------------------------------------------------------------------------
# Parser simples (e limitado) para arquivos XML/HTML.
# Obs.: Este parser é usado pelas Funções ZZ, não serve como parser genérico.
# Obs.: Necessário pois não há ferramenta portável para lidar com XML no Unix.
#
# Opções: --tidy Reorganiza o código, deixando uma tag por linha
# --tag Extrai (grep) uma tag específica
# --untag Remove todas as tags, deixando apenas texto
# --unescape Converte as entidades &foo; para caracteres normais
#
# Uso: zzxml [--tidy] [--tag NOME] [--untag] [--unescape] [arquivo(s)]
# Ex.: zzxml --tidy arquivo.xml
# zzxml --untag --unescape arquivo.xml # xml -> txt
# zzxml --tag title --untag --unescape arquivo.xml # títulos
# cat arquivo.xml | zzxml --tag item | zzxml --tag title # aninhado
#
# Autor: Aurelio Marinho Jargas, www.aurelio.net
# Desde: 2011-05-03
# Versão: 2
# Licença: GPL
# Requisitos: zzjuntalinhas
# ----------------------------------------------------------------------------
zzxml ()
{
zzzz -h xml "$1" && return

local tag
local tidy=0
local untag=0
local unescape=0

# Opções de linha de comando
while [ "${1#-}" != "$1" ]
do
case "$1" in
--tidy ) shift; tidy=1;;
--untag ) shift; untag=1;;
--unescape) shift; unescape=1;;
--tag ) shift; tidy=1 tag="$1"; shift;;
--* ) echo "Opção inválida $1"; return 1;;
* ) break;;
esac
done

# O código seguinte é um grande filtro, com diversos blocos de comando
# IF interligados via pipe (logo após o FI). Cada IF pode aplicar um
# filtro (sed, grep, etc) ao código XML, ou passá-lo adiante inalterado
# (cat -). Por esta natureza, a ordem dos filtros importa. O tidy deve
# ser sempre o primeiro, para organizar. O unescape deve ser o último,
# pois ele pode fazer surgir < e > no código.
#
# Essa estrutura toda de IFs interligados é bizarra e não tenho certeza
# se funciona em versões bem antigas do bash, mas acredito que sim. Fiz
# assim para evitar ficar lendo e gravando arquivos temporários para
# cada filtro. Como está, é tudo um grande fluxo de texto, que não usa
# arquivos externos. Mas se esta função precisar crescer, todo este
# esquema precisará ser revisto.

# Arquivos via STDIN ou argumentos
zztool file_stdin "$@" |

# --tidy
if test $tidy -eq 1
then
# Deixa somente uma tag por linha.
# Tags multilinha ficam em somente uma linha.
# Várias tags em uma mesma linha ficam multilinha.
# Isso facilita a extração de dados com grep, sed, awk...
#
# ANTES DEPOIS
# --------------------------------------------------------
# <a <a href="foo.html" title="Foo">
# href="foo.html"
# title="Foo">
# --------------------------------------------------------
# <p>Foo <b>bar</b></p> <p>
# Foo
# <b>
# bar
# </b>
# </p>

zzjuntalinhas -d ' ' |
sed '
# quebra linha na abertura da tag
s/</\
</g
# quebra linha após fechamento da tag
s/>/>\
/g' |
# Rejunta o conteúdo do <![CDATA[...]]>, que pode ter tags
zzjuntalinhas -i '^<!\[CDATA\[' -f ']]>$' -d '' |

# Remove linhas em branco (as que adicionamos)
sed '/^$/d'
else
cat -
fi |

# --tag
# É sempre usada em conjunto com --tidy (automaticamente)
if test -n "$tag"
then
sed -n "
# Tags de uma linha
# <foo bar='1' />
/^<$tag[> ].*\/>$/ p

# Tags multilinha
# <p>Foo
# <b>bar
# </b>
# </p>
/^<$tag[> ]/, /^<\/$tag>/ {
H
/^<\/$tag>/ {
s/.*//
x
s/\n//g
p
}
}"
else
cat -
fi |

# --untag
if test $untag -eq 1
then
# Caso especial: <![CDATA[Foo bar.]]>
sed 's/<!\[CDATA\[//g ; s/]]>//g ; s/<[^>]*>//g'
else
cat -
fi |

# --unescape
if test $unescape -eq 1
then
sed "
s/&quot;/\"/g
s/&amp;/\&/g
s/&apos;/'/g
s/&lt;/</g
s/&gt;/>/g
"
else
cat -
fi
}

Change log

r710 by aureliojargas on Mar 29, 2012   Diff
SEGURANÇA: $1 colocado entre aspas na
chamada padrão zzzz -h de todas as
funções.
Go to: 
Sign in to write a code review

Older revisions

r691 by aureliojargas on Mar 29, 2012   Diff
lint: padronizado o comentário para a
chamada de zztool file_stdin.
r655 by aureliojargas on Mar 23, 2012   Diff
s/Aurélio/Aurelio/ *
r486 by aureliojargas on May 20, 2011   Diff
COMBO: Arrumadas inconsistências de
espaços em branco na indentação de
várias funções. Foi usado o script
'alinhamento' para encontrar os
problemas. Estas alterações não mudam
...
All revisions of this file

File info

Size: 4220 bytes, 149 lines
Powered by Google Project Hosting