2017-06-09 52 views
5

Mam dwa pliki - jeden zawiera adresy (numery linii), a drugi dane w następujący sposób:Pick up linii z pliku w oparciu o numery linii w innym pliku

plik adres:

2 
4 
6 
7 
1 
3 
5 

plik danych

1.000451451 
2.000589214 
3.117892278 
4.479511994 
5.484514874 
6.784499874 
7.021239396 

Chcę losowy plik danych na podstawie liczby plików adresowych tak mam:

2.000589214 
4.479511994 
6.784499874 
7.021239396 
1.000451451 
3.117892278 
5.484514874 

Chcę to zrobić w pythonie lub bashie, ale jeszcze nie znalazłem żadnego rozwiązania.

+0

Czy plik adresowy zawiera numer wiersza lub 'int' liczb z pliku danych? – heemayl

+0

Tylko numery linii – hassan

+3

'Chcę to zrobić w pythonie lub w bash', a następnie wypróbować coś i dodać odpowiedni kod ... – Sundeep

Odpowiedz

2

Z awk:

awk 'NR==FNR {a[NR]=$0; next} {print a[$0]}' data.txt addr.txt 
  • NR==FNR {a[NR]=$0; next} tworzy tablicę asocjacyjną a z klawiszy jest rekord (wiersz) liczba i wartość bycia cały rekord, to byłoby zastosowanie tylko do pierwszego pliku (NR==FNR), który jest data.txt.next sprawia awk przejść do następnej linii bez przetwarzania rejestrują każde dalsze

  • {print a[$0]} wyświetla wartość z matrycy z kluczy, (addr.txt) linii (rejestr) Numer currect pliku jest

Przykład :

% cat addr.txt 
2 
4 
6 
7 
1 
3 
5 

% cat data.txt 
1.000451451 
2.000589214 
3.117892278 
4.479511994 
5.484514874 
6.784499874 
7.021239396 

% awk 'NR==FNR {a[NR]=$0; next} {print a[$0]}' data.txt addr.txt 
2.000589214 
4.479511994 
6.784499874 
7.021239396 
1.000451451 
3.117892278 
5.484514874 
+2

Ładne rozwiązanie i świetne wyjaśnienie. – codeforester

+0

Bardzo elastyczne zastosowanie w awk. – CWLiu

+0

fajna jakość odpowiedzi z wytłumaczeniem na przyszłość. PS: Nie miałem DV. –

0

można to zrobić, również w ramach Python, jak w poniższym przykładzie:

with open("address_file", 'r') as f1, open("data_file", "r") as f2: 
    data1 = f1.read().splitlines() 
    data2 = f2.read().splitlines() 

for k in data1: 
    # Handle exceptions if there is any 
    try: 
     print(data2[int(k)-1]) 
    except Exception: 
     pass 

Edit: jak sugeruje @heemayl, tutaj jest inne rozwiązanie przy użyciu tylko jednego list:

with open("file1", 'r') as f1, open("file2", 'r') as f2: 
    data = f2.read().splitlines() 

    for k in f1.read().splitlines(): 
     print(data[int(k)-1]) 

Zarówno wyjście wola:

2.000589214 
4.479511994 
6.784499874 
7.021239396 
1.000451451 
3.117892278 
5.484514874 
+2

Nie musisz mieć dwóch list. Po prostu utwórz listę dla pliku danych i wykonaj iteracje po liniach pliku z jedynie numerami linii. – heemayl

+0

Tak, wiem. Ale uważam, że OP może łatwo złapać to, co dzieje się wewnątrz kodu. Nie sądzę, że miał dobrą wiedzę, jak odpowiedzieć na to pytanie za pomocą Pythona. Ale wciąż twój komentarz jest poprawny. –

3

Jeśli nie mind sed, możemy użyć process substitution, aby osiągnąć ten łatwo:

sed -nf <(sed 's/$/p/' addr.txt) data.txt 
  • -n hamuje domyślne drukowania
  • -f sprawia sed czytać polecenia z substytucji procesowej <(...)
  • <(sed 's/$/p/' addr.txt) tworzy sed polecenia drukowania na podstawie numerów linii w addr.txt

Daje wyjście :

2.000589214 
4.479511994 
6.784499874 
7.021239396 
1.000451451 
3.117892278 
5.484514874