Tengo un archivo csv muy grande. ¿Cómo eliminarías el último ,
con sed (o similar)?
...
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0],
]
Salida deseada
...
[11911,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11912,0,"BUILDER","2014-10-15","BUILDER",0,0],
[11913,0,"BUILDER","2014-10-15","BUILDER",0,0]
]
El siguiente comando sed eliminará la última aparición por línea, pero quiero por archivo.
sed -e 's/,$//' foo.csv
Tampoco funciona
sed '$s/,//' foo.csv
Respuestas:
Utilizando
awk
Si la coma siempre está al final de la penúltima línea:
Usando
awk
ybash
Utilizando
sed
Para OSX y otras plataformas BSD, intente:
Utilizando
bash
fuente
sed: 1: "x;${s/,$//;p;x}; 2,$ p": extra characters at the end of x command
sed
y a menudo es diferente en formas sutiles. No tengo acceso a OSX para probar esto, pero por favor intentesed -n -e x -e '${s/,$//;p;x;}' -e '2,$ p' input
Simplemente puede probar el siguiente comando Perl one-liner.
Explicación:
,
Coincide con una coma.(?!.*,)
La anticipación negativa afirma que no habría una coma después de esa coma coincidente. Entonces coincidiría con la última coma.s
Y lo más importante es els
modificador DOTALL que hace que el punto coincida incluso con los caracteres de nueva línea.fuente
perl -0777 -pi -e 's/(.*),(.*?)/\1\2/s'
. Esto funciona porque el primero.*
es codicioso, mientras que el segundo no lo es.Eso debería eliminar solo la última aparición de a
,
en cualquier archivo de entrada, y aún imprimirá aquellos en los que,
no ocurra. Básicamente, almacena secuencias de líneas que no contienen una coma.Cuando encuentra una coma, intercambia el búfer de línea actual con el búfer de retención y de esa manera imprime simultáneamente todas las líneas que ocurrieron desde la última coma y libera su búfer de retención.
Estaba buscando en mi archivo de historial y encontré esto:
En realidad es bastante bueno. Sí, lo usa
eval
, pero nunca le pasa nada más allá de una referencia numérica a sus argumentos. Creased
scripts arbitrarios para manejar una última coincidencia. Te mostrare:Eso imprime lo siguiente para stderr. Esta es una copia de
lmatch
la entrada de:El
eval
subshell de la función ed recorre todos sus argumentos una vez. A medida que avanza sobre ellos, itera un contador de manera apropiada según el contexto de cada cambio y omite esa cantidad de argumentos para la próxima iteración. A partir de entonces, hace una de las pocas cosas por argumento:$a
a$o
.$a
se asigna en función del valor del$i
cual se incrementa por conteo de arg para cada arg procesado.$a
se le asigna uno de los dos valores siguientes:a=$((i+=1))
- esto se asigna si una opción corta no tiene su argumento adjunto o si la opción era larga.a=$i#-?
- esto se asigna si la opción es corta y no tener su arg anexa a la misma.a=\${$a}${1:+$d\${$(($1))\}}
- Independientemente de la asignación inicial,$a
el valor de siempre se incluye entre llaves y, en un-s
caso, a veces$i
se incrementa uno más y se agrega un campo delimitado adicionalmente.El resultado es que
eval
nunca se pasa una cadena que contenga incógnitas. Se hace referencia a cada uno de los argumentos de la línea de comandos por su número de argumento numérico, incluso el delimitador que se extrae del primer carácter del primer argumento y es la única vez que debe usar cualquier carácter que no esté escapado. Básicamente, la función es un generador de macros: nunca interpreta los valores de los argumentos de ninguna manera especial porquesed
puede (y lo hará, por supuesto) manejarlo fácilmente cuando analiza el script. En cambio, simplemente organiza sus argumentos en un guión viable.Aquí hay algunos resultados de depuración de la función en el trabajo:
Y así
lmatch
se puede usar para aplicar fácilmente expresiones regulares a los datos después de la última coincidencia en un archivo. El resultado del comando que ejecuté arriba es:... que, dado el subconjunto de la entrada del archivo que sigue a la última vez
/^.0/
que coincide, aplica las siguientes sustituciones:sdd&&&&d
- reemplaza$match
con 4 veces sí.sd'dsqd4
- la cuarta comilla simple que sigue al comienzo de la línea desde el último partido.sd"d\dqd2
- lo mismo, pero para comillas dobles y globalmente.Y así, para demostrar cómo se puede usar
lmatch
para eliminar la última coma en un archivo:SALIDA:
fuente
-m
opción y la hice obligatoria, cambié a múltiples argumentos para re y repl-s
y también implementé el manejo adecuado del delimitador. Creo que es a prueba de balas. Utilicé con éxito un espacio y una comilla simple como delimitador,Si la coma puede no estar en la penúltima línea
El uso
awk
ytac
:El
awk
comando es simple para hacer la sustitución la primera vez que se ve el patrón.tac
invierte el orden de las líneas en el archivo, por lo que elawk
comando termina eliminando el último coma.Me han dicho que
Puede ser más eficiente.
fuente
Si puedes usar
tac
:fuente
ver /programming/12390134/remove-comma-from-last-line
Esto me funcionó:
Mi mejor manera es eliminar la última línea y después de eliminar la coma, agregue el] char nuevamente
fuente
Prueba con a continuación
vi
:Explicación:
$-1
seleccione penúltima líneas
reemplazar\(,\)\(\_s*]\)
encuentra una coma seguida de]
y separada por espacios o nueva línea\2
reemplazar por\(\_s*]\)
ej. espacios o nueva línea seguidos por]
fuente
Prueba con el siguiente
sed
comando.fuente