2016-04-26 9 views
1

File1 gespeichert haben:

count line_num 
xy  55 
ab  67 

File2:

a|b|c 
d|e|f 

I 55 ausdrucken möchten, 67 Zeilennummern von file2

versuche:

#!/usr/bin/ksh 
while read file_name; do 
    line_num=`echo $file_name | awk '{print $2}'` 
    awk 'NR==$line_num{print;exit}' file2 >> file3.txt 
done < file1 

aber es funktioniert nicht!

Antwort

1

Sie awk können die Zeilennummern in einer Schleife zu lesen und sed aus den spezifischen Linien drucken:

while read a; do sed -n ${a}p f2.txt; done < <(awk 'NR>1{print$2}' f1.txt)

Wenn Sie eine größere Datei, die Leistung kann ein Problem sein, wie Ed darauf hingewiesen, in diesem Fall können Sie awk allein verwenden:

awk 'NR==FNR{if(NR>1)l[$2]=1;next}{if(l[FNR])print $0}' f1.txt f2.txt

Eine weitere Möglichkeit, zu verwenden ist xargs:

awk 'NR>1{print $2}' f1.txt | xargs -n1 -I {} sed -n {}p f2.txt

+0

Stellen Sie sicher, dass Sie [why-is-using-a-shell-loop-to-process-text-betrachtet-bad-practice] lesen (http://unix.stackexchange.com/questions/169716/why-is) - Verwenden-a-Shell-Schleife-zu-Prozess-Text-betrachtet-schlecht-Übung) zuerst. –

+1

Ja, wenn es eine Datei von bescheidener Größe ist, wird es viel langsamer sein als einfaches 'awk'. –

+0

Richtig also warum ** EVER ** es tun, da es nicht gerade kürzer ist als ein awk-Skript. btw verwende niemals den Buchstaben "l" als Variablennamen, da er viel zu sehr nach der Zahl "1" aussieht (in einigen Schriftarten nicht zu unterscheiden) und deinen Code so verschleiert. –

4

awk Verwenden Sie tun können:

awk 'NR==FNR{line[$2]; next} FNR in line' file1 file2 

Wir die erste Datei iterieren und speichern zweite Spalte in einer Karte line genannt (konnten wir die erste Zeile ignorieren, die der Header NR>1 durch tun, ist aber da es doesn‘ t enthalten Zahlen, die wir nicht brauchen). Sobald die erste Datei in map geladen ist, durchlaufen wir die zweite Datei und drucken Zeilen aus, die sich in unserer Karte befinden. NR und FNR sind awk-Variablen, die sich die Zeilennummern merken.

0

Verwenden Sed zu konstruieren ein Sed Einzeiler (im Fall von file1 sie ausgegeben hatte, und laufen sed -n "55p;67p;" file2):

sed -n "$(sed -n '2~1{s/.* //;s/.*/&p/p}' file1)" file2 

ein guter Werbung für awk, leider!

Verwandte Themen