GNU/Linux >> Tutoriales Linux >  >> Linux

reemplazar líneas en un archivo con líneas en otro por número de línea

Usando awk :

awk -v a='2,4,5,7' -v b='1,2,5,8' '
BEGIN { split(a, ax, ","); split(b, bx, ",");
        for(n in ax) mapping[ bx[n] ] =ax[n];
};
NR==FNR { if (FNR in mapping) hold[ mapping[FNR] ]=$0; next; };
{ print (FNR in hold)? hold[FNR]: $0; }' fileB fileA

Aquí, pasamos números de línea como un awk -v variable en a='...' (para el archivo A) y b='...' (para el archivo B), entonces split() en una matriz con carácter de coma como separador (tenga en cuenta que a y b eran variables, mientras que ahora ax y bx son matrices).

luego construimos otro mapping matriz de ax y bx arreglos para mapear las líneas que deben ser reemplazadas en el archivo A con las del archivo B;

ahora claves (o índices) del mapping matriz son los números de línea del archivo B y los valores de estas claves son los números de línea del archivo A, como se muestra a continuación:

el mapping matriz es:

Key    Value
1      2
2      4
5      5
8      7

ahora lo que necesitamos, es decir, solo leer los números de línea del archivo B que coinciden con las claves anteriores (FNR de 1 , 2 , 5 y 8 ), así que hacemos eso con:

NR==FNR { if (FNR in mapping) hold[ mapping[FNR] ]=$0; next; };

Bien, ahora cuál es el valor del mapping[FNR] ? si marcas el mapping matriz anterior, sería:

mapping[1] --> 2; then-we-have    hold[ mapping[1] ] --> hold[2]=$0
mapping[2] --> 4; then-we-have    hold[ mapping[2] ] --> hold[4]=$0
mapping[5] --> 5; then-we-have    hold[ mapping[5] ] --> hold[5]=$0
mapping[8] --> 7; then-we-have    hold[ mapping[8] ] --> hold[7]=$0

así que usamos el valor de mapping matriz como clave para el hold matriz y hold la matriz ahora contiene:

Key     Value
2       Argentina
4       Switzerland
5       Denmark
7       Colombia

ahora el último paso es usar claves en hold matriz como el número de línea coincidente en el archivo A y reemplace esas líneas con los valores de esa clave del hold matriz si ese número de línea se encuentra en la matriz o imprime la línea en sí misma si no se encuentra (operador ternario:condition? if-true : if-false ), y lo hacemos con:

{ print (FNR in hold)? hold[FNR]: $0; }

Usando sed estándar :

$ printf '%ds/^/%dc\\\\\\\n/p\n' 1 2 2 4 5 5 8 7 | sed -n -f /dev/stdin fileB | sed -f /dev/stdin fileA
Italy
Argentina
USA
Switzerland
Denmark
Japan
Colombia

La canalización de comandos,

printf '%ds/^/%dc\\\\\\\n/p\n' 1 2 2 4 5 5 8 7 |
sed -n -f /dev/stdin fileB |
sed -f /dev/stdin fileA

primero genera un sed declaración sustituta para cada par de números de línea usando printf . La salida del printf la llamada es la siguiente sed guión:

1s/^/2c\\\
/p
2s/^/4c\\\
/p
5s/^/5c\\\
/p
8s/^/7c\\\
/p

Este sed el script actúa en las líneas 1, 2, 5 y 8 e inserta nc\ seguido de una nueva línea literal (para algún número de línea n ) al comienzo de las líneas afectadas.

Ejecutando esto a través de fileB (con sed -n ) genera un nuevo sed guión:

2c\
Argentina
4c\
Switzerland
5c\
Denmark
7c\
Colombia

El c El comando reemplaza una línea con el texto que sigue al \ , por lo que la secuencia de comandos reemplazará las líneas 2, 4, 5 y 7.

Aplicando esto a fileA genera el resultado.

Leer los números de línea de un archivo en el que la primera columna contiene números de línea para fileB y la segunda columna contiene números de línea para fileA :

$ cat number-pairs
1 2
2 4
5 5
8 7
$ awk '{ printf "%ds/^/%dc\\\\\\\n/p\n", $1, $2 }' number-pairs | sed -n -f /dev/stdin fileB | sed -f /dev/stdin fileA
Italy
Argentina
USA
Switzerland
Denmark
Japan
Colombia

Obviamente puedes intercambiar $1 y $2 en él awk expresión si desea almacenar las columnas en el orden opuesto.


Linux
  1. ¿Cómo reemplazar una cadena en un archivo (s)?

  2. ¿Herramienta para obtener las líneas en un archivo que no están en otro?

  3. Reemplazar una palabra con otra en bash

  4. ¿Cómo reemplazar un archivo en jar con línea de comando en Linux?

  5. Reemplazo de SED en varias líneas

Cómo quitar líneas de un archivo usando el comando Sed

¿Reemplazar una línea con otro contenido usando Sed y paralelo para un archivo grande?

¿Reemplazar rango de líneas con rango de líneas (sed u otros)?

Cómo mostrar líneas específicas de un archivo en la línea de comandos de Linux

Tutorial de Unix Sed:anexar, insertar, reemplazar y contar líneas de archivos

Reemplazo de sed multilínea