Tengo el siguiente marco de datos que continúa indefinidamente horizontal y verticalmente con números negativos solo en las columnas impares:
-1 2 3 4 -5 9
2 3 -4 5 -6 11
Y quiero las columnas completas segunda, cuarta y sexta (o cada columna par) y los signos menos solo de la primera, tercera y quinta (o cada columna impar), así que obtengo esto:
- 2 4 - 9
3 - 5 - 11
Y finalmente termina con esto:
-2 4 -9
3 -5 -11
Por lo tanto, necesito los valores de las columnas pares sin cambios y de las columnas impares, si hay un valor negativo, mantenga el - solo y si hay un valor positivo, deséchelo.
¿Hay alguna manera de hacer esto con awk / sed?
Esto es más o menos lo que consigo:
awk '{ for (i=2;i<=NF;i+=2) $i="" }1' FILE.txt | sed 's/[0-9,.]*//g'
text-processing
sed
awk
Como se encuentra
fuente
fuente
Respuestas:
Aquí hay una manera:
El
awk
script recorre todas las columnas impares y establece su valor en-
si son negativas y si no están vacías. Luego,sed
elimina todos los espacios que siguen a-
ay luego reemplaza múltiples espacios consecutivos con uno solo. Tenga en cuenta que esto significa que la alineación se romperá, ya que algunos campos tendrán dos caracteres o más y otros tendrán uno. Eso no será un problema si está trabajando con campos, simplemente no se ven bonitos.fuente
El
sed
camino:Salida:
La primera expresión mata la columna final si hay un número impar de columnas. Lo hace buscando 0 o más pares
<number> <number>
, donde el primer número puede ser negativo.Editar: una
sed
solución más corta , inspirada en @mikeserv:Lo mismo con
perl
:Otra forma con
perl
(probablemente la más limpia):fuente
A
perl
uno:-an
dividir la entrada a la@F
matrizBEGIN{$,=" "}
establecer el separador de campo de salida en un espaciogrep{!($_%2)}0..$#F
obtener todos los índices pares en la@F
matriz, que son índices de elementos imparesmap{$_=$F[$_]=~/^-/?"-$F[$_+1]":" $F[$_+1]"}
verifique si el elemento impar comienza con-
, luego agregue-
al siguiente elemento par, de lo contrario agregue un espaciofuente
Como respuesta de @terdon pero sin el sed:
fuente
Una
python
solucionfuente
Una
awk
solución simple basada en las matemáticas :i=2
) al último campo (i<=NF
).$(i-1)
) con -1 o 1.printf "%4s"
) e imprima una nueva línea final (print ""
).La única advertencia a esto es que si tiene un número impar de columnas, el último campo no mostrará nada en absoluto. Espero que esto sea lo que esperas.Aparentemente esto es lo que esperas. :)(editado para trabajar con valores decimales y para que las condiciones del bucle estén más alineadas con la pregunta mientras se guardan 2 caracteres).
fuente
Necesitas olvidar lo negativo por completo, déjalo afuera. Desea consolidar dos campos, de izquierda a derecha. Eso es muy facil.
Observe cómo evito cualquier referencia al signo: cuando se procesa la entrada, el autómata aceptará solo espacios o números porque no entiende nada más; todo lo demás se ignora por completo y permanecerá en su lugar.
Cuando especifica un
\{
intervalo de repetición numérico\}
para una\(
subexpresión\)
, solo se\1
hace referencia a la última aparición de esa expresión . Por lo tanto, puede simplemente apretar, o truncar, un intervalo de repetición tan fácilmente. Y debido a que exprimimos la repetición detrás del signo, si hay uno, la segunda aparición de ese patrón seguirá a cualquier signo que precediera al primero.POSIX especifica el comportamiento descrito anteriormente para todas las aplicaciones compatibles con BRE, pero muy pocas
sed
lo hacen bien. GNU losed
hace.Por último, los espacios son solo para hacer que la aparición del patrón sea regular .
Por supuesto, esto nunca funcionará para ti. O, probablemente más correctamente, siempre funcionará para usted, pero nunca devolverá ningún resultado. ¿Cómo podría ser si el patrón es indefinido ?
fuente