Lo he intentado de muchas maneras, pero todavía no puedo lograr lo que quiero. Lo siento, todavía estoy aprendiendo.
Lo que quiero es así:
Archivo A.txt
5844
6069
6303
6309
Archivo B.txt
// some comment
// some explanation
100,5,3,8,,,
500,5,44,8,,,
//2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
5844,1,4,5844,,,
5900,5,2,8,,,
6069,5,4,8,,,
Quiero cambiar el número buscado de A.txt y comentar la línea en B.txt. A veces el número buscado puede aparecer en otra columna, por lo que solo cambiará la primera columna.
Resultado:
// some comment
// some explanation
100,5,3,8,,,
500,5,44,8,,,
2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
//5844,1,4,5844,,,
5900,5,2,8,,,
//6069,5,4,8,,,
Lo intenté y a veces se estropeaba y también cambiaba la otra columna. Luego usé algo como esto, es muy largo y no es fácil de modificar.
awk -F ',' '/^5844/ && $1="5844"{$1="//5844"}1' b.txt > c.txt; cp c.txt ba.txt; rm -rf b.txt; mv ba.txt b.txt
y a veces también se elimina el separador ','.
Por favor ayuda, muchas gracias.
Respuesta1
$ awk -F , 'FNR==NR { data[$1]=1; next } $1 in data { $0 = "//" $0 }; 1' 'File A.txt' 'File B.txt'
500,5,4,8,,,
5535,5,4,6069,,,
2121,5,4,8,,,
//5844,5,4,5844,,,
//6069,5,4,8,,,
Lo que estoy haciendo aquí es leer primero los números de File A.txt
las claves en la matriz asociativa data
. Luego pruebo cada primer campo para File B.txt
ver si es una entrada clave data
o no. Si es así, antepongo //
a la línea actual. Luego se imprimen todas las líneas, modificadas o no.
La FNR==NR
prueba solo será verdadera mientras se lee el primer archivo en la línea de comando y el bloque termina con next
. Esto significa que el primer bloque se ejecuta solo para el primer archivo, mientras que el segundo bloque se ejecuta para el segundo archivo, si el primer campo es una clave de la data
matriz.
El 1
al final activa la salida y podría reemplazarse por { print }
.
Lo anterior sóloagregar //
a las líneas en los segundos archivos que coinciden con los números en el primer archivo. a tambiéneliminar //
de lineasnocoincidente (es decir, para manejar su pregunta actualizada):
$ cat 'File B.txt'
// some comment
// some explanation
100,5,3,8,,,
500,5,44,8,,,
//2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
5844,1,4,5844,,,
5900,5,2,8,,,
6069,5,4,8,,,
$ awk -F , 'FNR==NR { data[$1]=1; next } FNR > 2 { if ($1 in data) $0 = "//" $0; else sub("^//","") }; 1' 'File A.txt' 'File B.txt'
// some comment
// some explanation
100,5,3,8,,,
500,5,44,8,,,
2500,5,2,8,,,
2121,5,2,8,,,
5535,5,4,6069,,,
//5844,1,4,5844,,,
5900,5,2,8,,,
//6069,5,4,8,,,
El awk
comando supone que desea pasar las dos primeras líneas File B.txt
sin cambios (de esto FNR > 2
se encarga la prueba). El FNR > 2
bloque prueba si el número es una entrada clave data
o no, y si lo es, la línea se comenta, pero si no lo es, //
se elimina cualquiera al comienzo de la línea usando sub()
.
En lugar de FNR > 2
eso, podría utilizar /^\/\/ /
para probar si hay un comentario en la parte superior del archivo. Esto requeriría que todos esos comentarios comiencen siempre con //
seguido de un espacio.
Las variables especiales NR
y FNR
contienen el número de líneas leídas hasta el momento en total ( NR
) y en el archivo actual ( FNR
).
Las comas "desaparecerían" si cambiara solo el primer campo, $1 = "//" $1
ya que eso reformaría el registro usando el valor actual de OFS
(un espacio por defecto). Podrías evitar esto usando BEGIN { OFS=FS }
, que se establecería OFS
en el carácter de coma (o cualquier carácter que uses -F
en la línea de comando).