GNU/Linux >> Tutoriels Linux >  >> Linux

remplacer les lignes d'un fichier par les lignes d'un autre par numéro de ligne

Utilisation de 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

Ici, nous passons les numéros de ligne comme un awk -v variable en a='...' (pour fichierA) et b='...' (pour fileB), alors on split() les dans un tableau sur le caractère virgule comme séparateur (notez que a et b étaient des variables, alors que maintenant ax et bx sont des tableaux).

puis on construit un autre mapping tableau de ax et bx tableaux pour mapper les lignes qui doivent être remplacées dans le fichier A avec celles du fichier B ;

maintenant les clés (ou index) du mapping array est les numéros de ligne du fichier B et les valeurs de ces clés sont les numéros de ligne du fichier A, comme ci-dessous :

le mapping tableau est :

Key    Value
1      2
2      4
5      5
8      7

alors maintenant, ce dont nous avons besoin, c'est-à-dire simplement lire les numéros de ligne du fichier B qui correspondent aux clés ci-dessus (FNR de 1 , 2 , 5 et 8 ), donc on fait ça avec :

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

OK, maintenant quelle est la valeur du mapping[FNR] ? si vous cochez le mapping tableau ci-dessus, ce serait :

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

nous avons donc utilisé la valeur de mapping tableau comme clé pour le hold tableau et hold tableau contient maintenant :

Key     Value
2       Argentina
4       Switzerland
5       Denmark
7       Colombia

maintenant la dernière étape consiste à utiliser les clés en hold tableau comme numéro de ligne correspondant dans le fichierA et remplacez ces lignes par les valeurs de cette clé à partir du hold tableau si ce numéro de ligne se trouve dans le tableau ou imprime la ligne elle-même si elle n'est pas trouvée (opérateur ternaire :condition? if-true : if-false ), et nous le faisons avec :

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

Utilisation de la norme 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

Le pipeline de commandes,

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

génère d'abord un sed instruction de substitution pour chaque paire de numéros de ligne en utilisant printf . La sortie du printf l'appel est le suivant sed script :

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

Ce sed le script agit sur les lignes 1, 2, 5 et 8 et insère nc\ suivi d'un retour à la ligne littéral (pour certains numéros de ligne n ) au début des lignes concernées.

Exécuter ceci sur fileB (avec sed -n ) génère un nouveau sed script :

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

Le c La commande remplace une ligne par le texte suivant le \ , le script remplacera donc les lignes 2, 4, 5 et 7.

Appliquer ceci à fileA génère le résultat.

Lecture des numéros de ligne d'un fichier dans lequel la première colonne contient des numéros de ligne pour fileB , et la deuxième colonne contient les numéros de ligne pour 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

Vous pouvez évidemment échanger $1 et $2 dans le awk expression si vous souhaitez stocker les colonnes dans l'ordre inverse.


Linux
  1. Remplacer une ligne par un autre contenu en utilisant Sed et Parallel pour un gros fichier ?

  2. Remplacer la plage de lignes par la plage de lignes (sed ou autres) ?

  3. Remplacer les lignes correspondant à un motif par des lignes d'un autre fichier dans l'ordre ?

  4. Remplacer la nouvelle ligne par Nul ?

  5. Comment remplacer sed comme texte par python?

Comment supprimer des lignes d'un fichier à l'aide de la commande Sed

Comment afficher des lignes spécifiques d'un fichier dans la ligne de commande Linux

Tutoriel Unix Sed :ajouter, insérer, remplacer et compter les lignes de fichiers

Remplacer un mot par un autre en bash

Recherche du contenu d'un fichier dans un autre fichier

Comment remplacer les guillemets simples par un autre caractère dans sed ?