Dado que el objetivo principal de este hilo es cómo hacer SAVE in-place en NON GNU, awk
entonces publico primero su plantilla que ayudará a cualquier persona en cualquier tipo de requisito, necesitan agregar / agregar BEGIN
y END
seccionar en su código manteniendo su BLOQUE principal según su requisito y debería hacer la edición in situ y luego:
NOTA: Siguiente escribirá toda su salida en output_file, por lo que en caso de que desee imprimir algo en la salida estándar, solo agregue laprint...
declaración sin> (out)
seguir.
Plantilla genérica:
awk -v out_file="out" '
FNR==1{
close(out)
out=out_file count++
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047"
}
{
.....your main block code.....
}
END{
if(rename){
system(rename)
}
}
' *.txt
Solución específica de la muestra proporcionada:
Se me ocurrió el siguiente enfoque dentro de awk
sí mismo (para las muestras agregadas, el siguiente es mi enfoque para resolver esto y guardar la salida en Input_file)
awk -v out_file="out" '
FNR==1{
close(out)
out=out_file count++
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047"
}
{
print FNR > (out)
}
END{
if(rename){
system(rename)
}
}
' *.txt
NOTA: esta es solo una prueba para guardar la salida editada en Input_file (s), uno podría usar su sección BEGIN, junto con su sección END en su programa, la sección principal debe cumplir con el requisito de la pregunta específica en sí.
Advertencia justa: también dado que este enfoque crea un nuevo archivo de salida temporal en la ruta, así que asegúrese de tener suficiente espacio en los sistemas, aunque en el resultado final esto mantendrá solo los Input_file (s) principales, pero durante las operaciones necesita espacio en el sistema / directorio
Lo siguiente es una prueba para el código anterior.
Ejecución del programa con un ejemplo: Supongamos que los siguientes son los.txt
Input_file (s):
cat << EOF > test1.txt
onetwo three
tets testtest
EOF
cat << EOF > test2.txt
onetwo three
tets testtest
EOF
cat << EOF > test3.txt
onetwo three
tets testtest
EOF
Ahora cuando ejecutamos el siguiente código:
awk -v out_file="out" '
FNR==1{
close(out)
out=out_file count++
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047"
}
{
print "new_lines_here...." > (out)
}
END{
if(rename){
system("ls -lhtr;" rename)
}
}
' *.txt
NOTA: Tengo lugarls -lhtr
en lasystem
sección intencionalmente para ver qué archivos de salida está creando (de manera temporal) porque más tarde los cambiará a su nombre real.
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test2.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test1.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test3.txt
-rw-r--r-- 1 runner runner 38 Dec 9 05:33 out2
-rw-r--r-- 1 runner runner 38 Dec 9 05:33 out1
-rw-r--r-- 1 runner runner 38 Dec 9 05:33 out0
Cuando hacemos una secuencia de comandos ls -lhtr
posterior awk
a la ejecución, solo podemos ver los .txt
archivos allí.
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test2.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test1.txt
-rw-r--r-- 1 runner runner 27 Dec 9 05:33 test3.txt
Explicación: Agregar una explicación detallada del comando anterior aquí:
awk -v out_file="out" ' ##Starting awk program from here, creating a variable named out_file whose value SHOULD BE a name of files which are NOT present in our current directory. Basically by this name temporary files will be created which will be later renamed to actual files.
FNR==1{ ##Checking condition if this is very first line of current Input_file then do following.
close(out) ##Using close function of awk here, because we are putting output to temp files and then renaming them so making sure that we shouldn't get too many files opened error by CLOSING it.
out=out_file count++ ##Creating out variable here, whose value is value of variable out_file(defined in awk -v section) then variable count whose value will be keep increment with 1 whenever cursor comes here.
rename=(rename?rename ORS:"") "mv \047" out "\047 \047" FILENAME "\047" ##Creating a variable named rename, whose work is to execute commands(rename ones) once we are done with processing all the Input_file(s), this will be executed in END section.
} ##Closing BLOCK for FNR==1 condition here.
{ ##Starting main BLOCK from here.
print "new_lines_here...." > (out) ##Doing printing in this example to out file.
} ##Closing main BLOCK here.
END{ ##Starting END block for this specific program here.
if(rename){ ##Checking condition if rename variable is NOT NULL then do following.
system(rename) ##Using system command and placing renme variable inside which will actually execute mv commands to rename files from out01 etc to Input_file etc.
}
} ##Closing END block of this program here.
' *.txt ##Mentioning Input_file(s) with their extensions here.
awk
(quizás en una subshell) o un{...}
grupo cerrado y luego escribir los resultados en el archivo de salida deseado (ya sea para cada archivo de entrada, o un archivo combinado para todos los archivos de entrada). Entonces, ¿simplemente redirige la salida de la subshell o grupo encerrado entre llaves al archivo actual en el que se está escribiendo? ¿Simplemente incluir una cadena de archivos de entrada siguiendo elawk
comando procesará secuencialmente todos los archivos (o algo similar)?awk {..} file1 .. fileX
escribir el archivo modificado como, por ejemplo,temp01
y en su próxima iteración mientras procesa el siguiente archivo, use amv -f tmp01 input01
para sobrescribir el archivo de entrada con los datos modificados; o (2) simplemente escriba un nuevo directorio./tmp/tmp01 ... ./tmp/tmp0X
durante la ejecución de laawk
secuencia de comandos y haga un seguimiento sobre los archivos del./tmp
directorio y, por ejemplo,mv -f "$i" "input_${i##*[^0-9]}"
(o cualquier expansión que necesite para reemplazar los archivos de entrada anteriores.awk
completar el código completo, la segunda opción es casi lo mismo que estoy usando en mi sugerencia. Le agradecería si pudiera hacer saber sus pensamientos sobre esa solución, señor.