¿Alguien puede sugerir una forma elegante de lograr esto?
Entrada:
test instant ()
test instant ()
...
test instant () //total 1000 lines
la salida debe ser:
test instant1 ()
test instant2 ()
test instant1000()
Las líneas vacías están en mis archivos de entrada y hay muchos archivos en el mismo directorio que necesito procesar a la vez.
Intenté esto para reemplazar muchos archivos en el mismo directorio y no funcionó.
for file in ./*; do perl -i -000pe 's/instance$& . ++$n/ge' "$file"; done
errores:
Substitution replacement not terminated at -e line 1.
Substitution replacement not terminated at -e line 1.
y también probé esto: perl -i -pe 's/instant/$& . ++$n/ge' *.vs
Funcionó, pero el índice siguió incrementándose de un archivo a otro. Me gustaría restablecer eso a 1 para el archivo diff. alguna buena sugerencia?
find . -type f -exec perl -pi -e 's/instant/$& . ++$n{$ARGV}/ge' {} +
funciona pero reemplazó todos los demás archivos no deben ser reemplazados. Prefiero reemplazar los archivos solo con "* .txt".

test instant ()?Respuestas:
o con GNU
awk:Para editar los archivos en el lugar, agregue la
-iopción aperl:O recursivamente:
Explicaciones
-pes procesar la entrada línea por línea, evaluar la expresión pasada-epara cada línea e imprimirla. Para cada línea, sustituimos (usando els/re/repl/flagsoperador)instantpor sí mismo ($&) y el valor incrementado de una variable++$n. Lagbandera es hacer la sustitución en todo el mundo (no sólo una vez), yepor lo que la sustitución se interpreta como código de Perl para e valuar (no una cadena fija).Para la edición en el lugar donde una invocación perl procesa más de un archivo, queremos
$nrestablecer en cada archivo. En su lugar, usamos$n{$ARGV}(donde$ARGVestá el archivo procesado actualmente).El
awkque merece un poco de explicación.Estamos utilizando la capacidad de GNU
awkpara separar registros en cadenas arbitrarias (incluso expresiones regulares). Con-vRS=instant, configuramos el separador de registro eninstant.RTes la variable que contiene lo que coincideRS, por lo general,instantexcepto por el último registro donde será la cadena vacía. En la entrada anterior, los registros ($0) y los terminadores de registro (RT) son ([$0|RT]):Entonces, todo lo que tenemos que hacer es insertar un número incremental al comienzo de cada registro, excepto el primero.
Que es lo que hacemos arriba. Para el primer registro,
nestará vacío. Configuramos ORS (el separador de registro de salida ) a RT, para que seawkimpriman $0 RT. Lo hace sobre la segunda expresión (++n), que es una condición que siempre se evalúa como verdadera (un número distinto de cero) y, por lo tanto, la acción predeterminada (de impresión$0 ORS) se realiza para cada registro.fuente
sedRealmente no es la mejor herramienta para el trabajo, desea algo con mejores capacidades de secuencias de comandos. Aquí hay algunas opciones:perl
El
-pmedio "imprime cada línea" después de aplicar cualquier script que se le dé-e. Las-000vueltas en "modo de párrafo" lo que los registros (líneas) se definen por salto de línea consecutiva (\n) caracteres, esto permite que se maneja correctamente las líneas a doble espacio.$&es el último patrón coincidente y$.es el número de línea actual del archivo de entrada. Eleens///eme permite evaluar expresiones en el operador de sustitución.awk (esto supone que sus datos son exactamente como se muestran, con tres campos separados por espacios)
Aquí, incrementamos la
kvariableksolo si la línea actual no está vacía,/./en cuyo caso también imprimimos la información necesaria. Las líneas vacías se imprimen tal cual.varias conchas
Aquí, cada línea de entrada se divide automáticamente en espacios en blanco y los campos se guardan como
$a,$by$c. Luego, dentro del ciclo,$cse aumenta en uno para cada línea para la que$ano está vacía y su valor actual se imprime al lado del segundo campo$b,.NOTA: todas las soluciones anteriores suponen que todas las líneas del archivo tienen el mismo formato. Si no, la respuesta de @ Stephane es el camino a seguir.
Para tratar con muchos archivos y suponer que desea hacer esto a todos los archivos en el directorio actual, puede usar esto:
CUIDADO: Esto supone nombres de archivos simples, sin espacios, si es necesario para hacer frente a algo más complejo, ir a (suponiendo
ksh93,zshobash):fuente