GNU/Linux >> Znalost Linux >  >> Linux

nahradit řádky v jednom souboru řádky v jiném číslem řádku

Pomocí 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

Zde předáváme čísla řádků jako awk -v ariable v a='...' (pro soubor A) a b='...' (pro soubor B), pak jsme split() do pole se znakem čárky jako oddělovačem (všimněte si, že a a b byly proměnné, zatímco nyní ax a bx jsou pole).

pak vytvoříme další mapping pole z ax a bx pole k mapování řádků, které by měly být nahrazeny v souboru A řádky ze souboru B;

nyní klíče (nebo indexy) mapping pole jsou čísla řádků souboruB a hodnoty těchto klíčů jsou čísla řádků souboruA, jak je uvedeno níže:

mapping pole je:

Key    Value
1      2
2      4
5      5
8      7

takže teď to, co potřebujeme, tedy jen přečíst čísla řádků ze souboru B, která odpovídají výše uvedeným klíčům (FNR 1 , 2 , 5 a 8 ), takže to uděláme pomocí:

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

OK, teď jaká je hodnota mapping[FNR] ? pokud zaškrtnete mapping pole výše, to by bylo:

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

takže jsme použili hodnotu mapping pole jako klíč pro hold pole a hold pole nyní obsahuje:

Key     Value
2       Argentina
4       Switzerland
5       Denmark
7       Colombia

nyní posledním krokem je použití klíčů v hold pole jako odpovídající číslo řádku v souboru A a nahraďte tyto řádky hodnotami tohoto klíče z hold pole, pokud je toto číslo řádku nalezeno v poli, nebo vytiskněte samotný řádek, pokud nebylo nalezeno (ternární operátor:condition? if-true : if-false ), a to pomocí:

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

Pomocí standardního 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

Příkazový kanál,

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

nejprve vygeneruje sed nahradit příkaz pro každý pár čísel řádků pomocí printf . Výstup printf volání je následující sed skript:

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

Toto sed skript funguje na řádku 1, 2, 5 a 8 a vloží nc\ následovaný doslovným novým řádkem (pro některé číslo řádku n ) na začátku dotčených řádků.

Spuštění přes fileB (s sed -n ) vygeneruje nový sed skript:

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

c příkaz nahradí řádek textem následujícím za \ , takže skript nahradí řádky 2, 4, 5 a 7.

Toto použijete na fileA vygeneruje výsledek.

Čtení čísel řádků ze souboru, ve kterém první sloupec obsahuje čísla řádků pro fileB a druhý sloupec obsahuje čísla řádků pro 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

Samozřejmě můžete vyměnit $1 a $2 v awk výraz, pokud chcete ukládat sloupce v opačném pořadí.


Linux
  1. Nástroj pro získání řádků v jednom souboru, které nejsou v jiném?

  2. Rozdělit soubor podle počtu řádků včetně záhlaví v každém z nich?

  3. SED nahradit na více řádcích

  1. Jak zobrazit konkrétní řádky souboru v příkazovém řádku Linuxu

  2. Jak nahradit text podobný sedu pythonem?

  3. Nahraďte slovo jiným v bash

  1. Hledání obsahu jednoho souboru v jiném souboru

  2. Jak nahradím jednoduché uvozovky jiným znakem v sed?

  3. Jak nahradit soubor v jar příkazovým řádkem v linuxu?