GNU/Linux >> Linux Esercitazione >  >> Linux

sostituire le righe in un file con le righe in un altro per numero di riga

Utilizzando 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

Qui passiamo i numeri di riga come awk -v ariabile in a='...' (per fileA) e b='...' (per fileB), quindi split() in un array sul carattere virgola come separatore (nota che a e b erano variabili, mentre ora ax e bx sono array).

poi costruiamo un altro mapping matrice da ax e bx array per mappare le linee che devono essere sostituite nel fileA con quelle del fileB;

ora chiavi (o indici) del mapping array sono i numeri di riga del fileB e i valori di queste chiavi sono i numeri di riga del fileA, come di seguito:

il mapping matrice è:

Key    Value
1      2
2      4
5      5
8      7

quindi ora ciò di cui abbiamo bisogno, cioè solo leggere i numeri di riga dal fileB che corrispondono alle chiavi sopra (FNR di 1 , 2 , 5 e 8 ), quindi lo facciamo con:

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

OK, ora qual è il valore di mapping[FNR] ? se selezioni mapping array sopra, sarebbe:

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

quindi abbiamo utilizzato il valore di mapping array come chiave per hold matrice e hold l'array ora contiene:

Key     Value
2       Argentina
4       Switzerland
5       Denmark
7       Colombia

ora l'ultimo passo è usare le chiavi in ​​hold array come numero di riga corrispondente nel fileA e sostituisci quelle righe con i valori di quella chiave dal hold array se quel numero di riga è stato trovato nell'array o stampa la riga stessa se non è stata trovata (operatore ternario:condition? if-true : if-false ), e lo facciamo con:

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

Utilizzando lo standard sed :

$ 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 pipeline dei comandi,

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

prima genera un sed sostituire l'istruzione per ogni coppia di numeri di riga utilizzando printf . L'output di printf call è il seguente sed script:

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

Questo sed lo script agisce sulla riga 1, 2, 5 e 8 e inserisce nc\ seguito da una nuova riga letterale (per alcuni numeri di riga n ) all'inizio delle righe interessate.

Eseguendolo su fileB (con sed -n ) genera un nuovo sed script:

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

Il c Il comando sostituisce una riga con il testo che segue il \ , quindi lo script sostituirà le righe 2, 4, 5 e 7.

Applicando questo a fileA genera il risultato.

Lettura dei numeri di riga da un file in cui la prima colonna contiene i numeri di riga per fileB e la seconda colonna contiene i numeri di riga per 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

Puoi ovviamente scambiare $1 e $2 in lui awk expression se desideri memorizzare le colonne nell'ordine opposto.


Linux
  1. Come sostituire una stringa in un file?

  2. Dividi il file per numero di righe inclusa l'intestazione in ciascuna?

  3. Eliminazione di righe specifiche da un file nella riga di comando di Linux

  4. Sostituisci una parola con un'altra in bash

  5. Come sostituire un file in jar con la riga di comando in Linux?

Come rimuovere le righe da un file usando il comando Sed

Come visualizzare righe specifiche di un file nella riga di comando di Linux

Tutorial Unix Sed:aggiungi, inserisci, sostituisci e conta righe di file

Come sostituire il testo come sed con python?

Trovare il contenuto di un file in un altro file

Come posso sostituire le virgolette singole con un altro carattere in sed?