2017-04-12 1 views
1

Ich habe eine Datei, sagen wir A.txt, die etwa 80.000 Zeilen, aber 2 Felder hat. Beispiel Linien aussehen wie unten:Wie die folgende Aufgabe in Shell-Skript mit Grep aber ohne eine For-Schleife zu tun?

utt1 f 
utt2 f 
utt3 m 
utt4 f 

Ich habe eine zweite Datei B.txt, die mehr Art und Weise mehr Zeilen als A.txt hat und hat zwei Felder. Beispiel Linien aussehen wie unten

utt1_1 somethingHere  
utt1_2 somethingElse  
utt2_1 someText  
utt2_2 somemore  
utt2_3 someMore  
utt3_1 someText  
utt4_1 somemore  
utt4_2 abcd  
utt4_3 aanan 

Das erste Feld in B.txt ist grundsätzlich die gleiche wie erstes Feld in A.txt gefolgt von _something (Jede Zeile wird variable Anzahl von Malen wiederholt).

Meine Aufgabe ist es, eine Datei zu erstellen, die wie diese für die Geschlechter

utt1_1 f  
utt1_2 f  
utt2_1 f  
utt2_2 f  
utt2_3 f  
utt3_1 m  
utt4_1 f  
utt4_2 f  
utt4_3 f 

‚f‘ und ‚m‘ beginnt aussieht. mit anderen Worten, was ich tun möchte, ist, utt und gender Informationen von A.txt und grep für die Äußerung in B.txt zu bekommen und das erste Feld mit dem richtigen Geschlecht zu kartieren. Ich tue es eine Weile Schleife wie folgt:

while read utt gen; do 
    grep $utt B.txt | awk -v gen=$gen '{print $1" "gen}' 
done < A.txt 

Da ich es in einer Schleife und einer Länge von A.txt tue, ist groß, es viel Zeit nimmt die Aufgabe abzuschließen. Könntest du mir einen schnelleren Weg vorschlagen, es mit bash zu machen?

Danke

+0

Möchten Sie es mit bash/awk usw. machen? Du hast die Frage mit Python getaggt, also ... –

+0

Python oder Bash, ohne ein separates Skript schreiben zu müssen. Ich möchte es nur innerhalb von ein oder zwei Zeilen erledigen. Dies wäre eine Teilaufgabe in einem großen Shell-Skript, das bereits – user1540393

+0

@Inian hat es tatsächlich so aussieht – user1540393

Antwort

5

Dies ist maßgeschneidert Job für awk 2 Dateiverarbeitung:

awk 'FNR == NR {a[$1] = $2; next} $1 in a {print $1 "_" $2, a[$1]}' file1 FS='[_ ]' file2 
utt1_1 f 
utt1_2 f 
utt2_1 f 
utt2_2 f 
utt2_3 f 
utt3_1 m 
utt4_1 f 
utt4_2 f 
utt4_3 f 

Argumente file1 FS='[_ ]' file2 Satz Eingabefeld Separator _ oder Raum für file2 nur.

Referenz:Effective AWK Programming

+0

@ user1540393: Hat das geklappt? – anubhava

1

Eine weitere in awk, diesmal mit split:

$ awk 'NR==FNR{a[$1]=$2;next}{split($1,b,"_");if(i=b[1] in a)print $1,a[b[1]]}' file1 file2 
utt1_1 f 
utt1_2 f 
utt2_1 f 
utt2_2 f 
utt2_3 f 
utt3_1 m 
utt4_1 f 
utt4_2 f 
utt4_3 f 

Erklärt:

NR==FNR {     # process the first file 
    a[$1]=$2    # hash it to a hash with $2 as value 
    next }     # move to next record 
{       # process the second (or any number of) file 
    split($1,b,"_")   # split the $1 on _ 
    if(i=b[1] in a)   # first part of b is the key to hash 
     print $1,a[b[1]] } # output $1 and hash value 
' file1 file2 
0
awk '$1 !~ /_/ { lst[$1]=$2 } $1 ~ /_/ { print $1" "lst[substr($1,1,4)] }' file1 file2 

Wenn die Datei Felder enthalten, die nicht tun Muster mit _ abgestimmt und dann hinzugefügt sie zu einem Array, sonst drucken Sie die erste Zeichenfolge in jeder Datei zusammen mit dem Wert in dem Array, das wir erstellt haben.

Verwandte Themen