Muy bien, parece que no puedo encontrar una manera de hacer lo que necesito.
Digamos que tengo un archivo de texto A como este
(freqBiasL2[27])
(SatBiasL1[27])
(defSatBiasL2_L1[27])
(defSatBiasSlope[27])
(defSatBiasSigma[27])
(freqBiasL2[28])
(SatBiasL1[28])
(defSatBiasL2_L1[28])
(defSatBiasSlope[28])
(defSatBiasSigma[28])
(freqBiasL2[29])
(SatBiasL1[29])
(defSatBiasL2_L1[29])
(defSatBiasSlope[29])
(defSatBiasSigma[29])
etcétera. Quiero cambiar el índice entre corchetes [] de modo que cada índice i sea = i+3.
Lo intenté con una combinación de bucle for y sed, pero no funcionó.
for i in {27..107..1}
do
i_new=$((i+3))
sed -e 's/\['$i'\]/\['$i_new'\]/' prova.txt
done
El problema es que cambiará los primeros 27 por 30 pero en próximas interacciones encontrará 2 bloques con índice 30 (el cambiado y el original).
¿Cómo puedo hacerlo sin sobrescribir los índices ya modificados?
Ok, gracias, edito mi pregunta para mejorar: ¿Cómo puedo hacer algo similar si tengo 2 índices como:
(freqBiasL2[32][100])
(SatBiasL1[32][101])
(defSatBiasL2_L1[32][102])
(defSatBiasSlope[32][103])
(defSatBiasSigma[32][104])
¿Y quiero incrementar solo el segundo índice ignorando el primero?
Respuesta1
Utilice Perl:
perl -pe 's/(?<=\[)(\d+)(?=\])/$1+1/ge' prova.txt
Explicación:
-p
significa recorrer cada línea e imprimir el resultado después de cada línea-e
define la expresión a ejecutar en cada líneas/from/to/
hace una simple sustitucións/(\d+)/$1+1/ge
coincide con uno o más dígitos, los captura en$1
y luego ele
modificador al final le dice a Perl que la cadena de sustitución es una expresión:$1+1
sustituye el valor de$1
más 1. Elg
modificador significa hacer esta sustitución globalmente, es decir, más de una vez por línea.(?<=\[)
es una afirmación positiva de longitud cero. Eso significa que lo que viene después solo coincide si está precedido por[
(que debe tener un carácter de escape,\
ya que[
es un token especial en las expresiones regulares). Lo de la longitud cero significa que no es parte de lo que será reemplazado.(?=\])
es una afirmación positiva de anticipación de longitud cero. Eso significa que lo que viene antes solo coincide si va seguido de]
(nuevamente escapó).
Entonces esto tomará todos los números entre [
y ]
e incrementará ese número.
Respuesta2
También podrías usar awk
:
awk -F '[\\[\\]]' '{if ($2) { sub($2, $2 + 3)}} 1' prova.txt
De hecho, esto se puede reducir ligeramente a:
awk -F '[\\[\\]]' '$2 { sub($2, $2 + 3)} 1' prova.txt
Respuesta3
Sé que ya resolvió su problema, pero para su información, podría haberlo resuelto con una modificación muy simple de su código: invirtiendo la secuencia que recorre.
Usar {107..27..-1}
(o más concisamente {107..27}
) hubiera sido suficiente para solucionar tu problema, ya que al reemplazar 30 solo se habrían encontrado los 30 originales, no habiendo sido reemplazados los 27 aún.
Respuesta4
Ok, creo que tengo una solución para el doble índice y también modifico el comando de cas. Esto hace que el trabajo:
perl -p -e 's/\[(\d+)\]\[(\d+)\]/"[" . ($1) . "][" . ($2+40) . "]"/ge' prova.txt
Por cierto, no estoy seguro de por qué necesito . ($1) .
(punto con espacio en blanco).