2011-12-20 28 views
10

Chip, Dirkland, DrobæSphere Inc, cdirkland @ hotmail.com, EE.UU.Skip/eliminar caracteres no ASCII con sed

que he estado tratando de usar sed para modificar direcciones de correo electrónico en un archivo .csv pero la línea por encima de mí sigue tropezar, usando comandos como:

sed -i 's/[\d128-\d255]//' FILENAME 

from this stackoverflow question

no parece funcionar como me sale un error 'no válido carácter de intercalación'.

Idealmente, no quiero cambiar el carácter AE combinado en absoluto, preferiría saltearlo ya que no estoy tratando de manipular ese texto sino las direcciones de correo electrónico. Mientras ese AE esté ahí, aunque cause que mi sustitución sed falle después de una línea, elimine el carácter y procese bien el archivo completo.

¿Alguna idea?

Respuesta

4

Esto podría funcionar para usted (GNU SED):

echo "Chip,Dirkland,DrobæSphere Inc,[email protected],usa" | 
sed 's/\o346/a+e/g' 
Chip,Dirkland,Droba+eSphere Inc,[email protected],usa 

Luego hacer lo que tiene que hacer y después de volver a hacer:

echo "Chip,Dirkland,Droba+eSphere Inc,[email protected],usa" | 
sed 's/a+e/\o346/g' 
Chip,Dirkland,DrobæSphere Inc,[email protected],usa 

Si tiene caracteres difíciles de cuerdas y desea para comprender cómo sed los ve usar el comando l0 (ver here). También es muy útil para depurar expresiones regulares difíciles.

echo "Chip,Dirkland,DrobæSphere Inc,[email protected],usa" | 
sed -n 'l0' 
Chip,Dirkland,Drob\346Sphere Inc,[email protected],usa$ 
+0

+1 para el 'l0'. También hay otro script 'sedsed.py', disponible [aquí] (http://aurelio.net/sedsed/). Útil para inspeccionar los espacios 'pattern' y' hold'. No podría ayudar en este caso, pero una herramienta de depuración útil, no obstante. :) –

+0

ese comando sed -n 'l0' es interesante, lo que imprime para la empresa es: Drob \ 357 \ 277 \ 275Sphere Inc – xref

+0

y todavía no puedo obtener los ejemplos anteriores para trabajar con él, tal vez el personaje (que se muestra como un AE en Windows LibreOffice pero en ningún otro lugar) es en realidad un personaje especial que dice que no se puede representar en unicode? http://www.fileformat.info/info/unicode/char/fffd/index.htm – xref

0

¿Qué le parece usar awk para esto. Configuramos el Separador de campo a nada. Luego recorre cada personaje. Use un if loop para verificar si coincide con nuestro character class. Si lo hacemos, lo imprimimos o lo ignoramos.

awk -v FS="" '{for(i=1;i<=NF;i++) if($i ~ /[A-Za-z,[email protected] ]/) printf $i}' 

prueba:

[jaypal:~/Temp] echo "Chip,Dirkland,DrobæSphere Inc,[email protected],usa" | 
awk -v FS="" '{for(i=1;i<=NF;i++) if($i ~ /[A-Za-z,[email protected] ]/) printf $i}' 
Chip,Dirkland,DrobSphere Inc,[email protected],usa 

Actualización:

awk -v FS="" '{for(i=1;i<=NF;i++) if($i ~ /[A-Za-z,[email protected] ]/) printf $i; printf "\n"}' <datafile.csv> asciidata.csv 

He añadido printf "\ n" después del bucle para mantener las líneas se separan.

+0

Gracias Jaypal, ¿cómo podría esto ser modificado si desea procesar datafile.csv y salida asciidata.csv? – xref

+0

He actualizado la respuesta. ¡Espero que ayude! –

+0

Si solo quiere que la dirección de correo electrónico sea extraída de su archivo de entrada, 'awk' puede hacer eso en un abrir y cerrar de ojos sin ningún complejo' regex'. Avísame que tal funciono. –

4
sed -i 's/[^[:print:]]//' FILENAME 

Además, este actúa como dos2unix

+0

No funciona. [: print:] no es lo mismo que ASCII, p. 'ü' es imprimible pero no ASCII. –

1

Vine aquí probando este comando sed s/[\x00-\x1F]/ /g;, que me dio el mismo mensaje de error.

en este caso, simplemente basta con quitar el \x00 de la colación, produciendo s/[\x01-\x1F]/ /g;

Desgraciadamente parece que todos los caracteres arriba y que incluye \x7F y algunos otros se desecharon, como se puede ver con esta corta secuencia de comandos:

for ((i=0; i<=255; i++)); do 
    printf "== $i - \x$(echo "ibase=10;obase=16;$i" | bc) ==" 
    echo '' | sed -E "s/[\d$i-\d$((i+1))]]//g" 
done 

Tenga en cuenta que el problema es solo el uso de esos caracteres para especificar un rango. Todavía puede enumerarlos todos manualmente o por script. P.ej. a volver a su ejemplo:

sed -i 's/[\d128-\d255]//' FILENAME 

se convertiría en

c=; for ((i=128; i<255; i++)); do c="$c\d$i"; done 
sed -i 's/['"$c"']//' FILENAME 

cual se traduciría en:

sed -i 's/[\d128\d129\d130\d131\d132\d133\d134\d135\d136\d137\d138\d139\d140\d141\d142\d143\d144\d145\d146\d147\d148\d149\d150\d151\d152\d153\d154\d155\d156\d157\d158\d159\d160\d161\d162\d163\d164\d165\d166\d167\d168\d169\d170\d171\d172\d173\d174\d175\d176\d177\d178\d179\d180\d181\d182\d183\d184\d185\d186\d187\d188\d189\d190\d191\d192\d193\d194\d195\d196\d197\d198\d199\d200\d201\d202\d203\d204\d205\d206\d207\d208\d209\d210\d211\d212\d213\d214\d215\d216\d217\d218\d219\d220\d221\d222\d223\d224\d225\d226\d227\d228\d229\d230\d231\d232\d233\d234\d235\d236\d237\d238\d239\d240\d241\d242\d243\d244\d245\d246\d247\d248\d249\d250\d251\d252\d253\d254\d255]//' FILENAME 
+0

"_Por desgracia, parece que todos los caracteres anteriores e incluyendo \ x7F y algunos otros están desautorizados_". ¡Gracias! Eso explica por qué obtengo el error 'Carácter de intercalación no válido'. – xpt

Cuestiones relacionadas