Ignorando delimitatori sfuggiti (virgole) con awk?
Domanda
Se avessi una stringa con le virgole sfuggito in questo modo:
a,b,{c\,d\,e},f,g
Come potrei usare awk per analizzare che nelle seguenti voci?
a
b
{c\,d\,e}
f
g
Soluzione
{
split($0, a, /,/)
j=1
for(i=1; i<=length(a); ++i) {
if(match(b[j], /\\$/)) {
b[j]=b[j] "," a[i]
} else {
b[++j] = a[i]
}
}
for(k=2; k<=length(b); ++k) {
print b[k]
}
}
- Suddiviso in serie
a
, usando ',
' come delimitatore - Costruire matrice
b
daa
, linee fusione che terminano in '\
' - Stampa serie
b
(Nota: Inizia alle 2 dal primo elemento è vuoto)
Questa soluzione presume (per ora) che ',
' è l'unico personaggio che è sempre cavata con '\
' - vale a dire, non v'è alcuna necessità di gestire qualsiasi \\
nell'input, nè combinazioni strane, come \\\,\\,\\\\,,\,
.
Altri suggerimenti
{
gsub("\\\\,", "!Q!")
n = split($0, a, ",")
for (i = 1; i <= n; ++i) {
gsub("!Q!", "\\,", a[i])
print a[i]
}
}
Non credo awk ha alcun supporto integrato per qualcosa di simile. Ecco una soluzione che non è quasi più breve DigitalRoss di, ma dovrebbe avere alcun pericolo di mai accidentalmente colpire la stringa di made-up (! Q!). Dal momento che mette alla prova con una if
, si potrebbe anche estendere ad essere attenti sul fatto che in realtà hanno \\,
alla fine della stringa, che dovrebbe essere una barra sfuggito, non virgola.
BEGIN {
FS = ","
}
{
curfield=1
for (i=1; i<=NF; i++) {
if (substr($i,length($i)) == "\\") {
fields[curfield] = fields[curfield] substr($i,1,length($i)-1) FS
} else {
fields[curfield] = fields[curfield] $i
curfield++
}
}
nf = curfield - 1
for (i=1; i<=nf; i++) {
printf("%d: %s ",i,fields[i])
}
printf("\n")
}