Вывести строки файла1, который появляется в файле2 в awk - PullRequest
1 голос
/ 29 июня 2019

Я хочу напечатать языки программирования в файле1, который появляется в файле2, соответствующий ему номер строки в файле2 и полную строку файла 2.

file1 выглядит так:

Ruby
Visual Basic
Objective-C
C
R
C++
Basic

file2 выглядит так:

5. ab cde fg Java hij kl
2. ab PHP dddf llf 
4. cde fg z o Objective-C oode
8. a12b cde JavaScript kdk
6. ab99r cde Visual Basic llso dkd
1. lkd dsk Ruby kksdk
3. Python dsdls
9. CSS dkdsk
4. Jdjdj C Jjd Kkd
12. Iiii Jjd R Hhd
5. Jjjff C++ jdjejd
7. Jfjfjdoo Uueye Basic Jje Tasdk

Я хотел бы получить этот вывод:

 6|Ruby|1. lkd dsk Ruby kksdk
 5|Visual Basic|6. ab99r cde Visual Basic llsodkd            
 3|Objective-C|4. cde fg z o Objective-C oode
 9|C|4. Jdjdj C Jjd Kkd  
 10|R|12. Iiii Jjd R Hhd 
 11|C++|5. Jjjff C++ jdjejd
 12|Basic|7. Jfjfjdoo Uueye Basic Jje Tasdk 

где 6,5 и 3 - номер строки, в которой в файле 2. появляются "Ruby", "Visual Basic" и "Objective-C".

До сих пор я пытался использовать приведенный ниже код, но этот код работает, только если в файле 2 есть список точных совпадений при сравнении с файлом file1.

awk 'NR == FNR{a[$0];next} ($0 in a)' file1 file2

В этом случае языки программирования в файле2 содержат текст до и после, и я застрял в том, как получить желаемый результат.

Заранее спасибо за любую помощь.

Ответы [ 2 ]

3 голосов
/ 29 июня 2019

Не могли бы вы попробовать следующее (изменено index использование в коде согласно советам @Ed Morton sir).

awk -v OFS='|' '
FNR==NR{
  a[$0]
  next
}
{
  for(i in a){
     if(index(" "$0" "," "i" ")){
         print FNR,i,$0
     }
  }
}
'  Input_file1  Input_file2 | sort -t'|' -nr

Вывод будет следующим.

6|Ruby|1. lkd dsk Ruby kksdk
5|Visual Basic|6. ab99r cde Visual Basic llso dkd
3|Objective-C|4. cde fg z o Objective-C oode

Объяснение: Добавление пояснения к приведенному выше коду сейчас.

awk -v OFS='|"' '                           ##Starting awk program here.
FNR==NR{                                   ##Checking condition FNR==NR which will be TRUE when first Input_file is being read.
  a[$0]                                 ##creating an array named a whose index is $0 and value is $0.
}
{                                          ##Starting block here.
  for(i in a){                             ##Starting a for loop here.
     if(index(" "$0" "," "i" ")){                   ##checking if value of a[i] array present in current line.
         print FNR,i,$0             ##If above is TRUE then print FNR"|"i"|"$0 as per OP need.
     }
  }
}
'  file1  file2 | sort -t'|' -nr           ##Mentioning Input_files names here and passing its output into sort command and sorting it with reverse order.
1 голос
/ 29 июня 2019

С помощью GNU awk для sorted_in для поиска самых длинных языков (например, Visual Basic) сначала и удаления их из текущей строки, поскольку они найдены, чтобы более короткие языки, которые входят в их состав (например, Basic), могли ' внутри них не найти:

$ cat tst.awk
BEGIN { OFS="|" }
NR==FNR {
    lengths[$0] = length($0)
    next
}
{
    line = " " $0 " "
    PROCINFO["sorted_in"] = "@val_num_desc"
    for (lang in lengths) {
        if ( s = index(line," "lang" ") ) {
            print FNR, lang, $0
            line = substr(line,1,s) substr(line,s+1+lengths[lang])
        }
    }
}

$ awk -f tst.awk file1 file2
3|Objective-C|4. cde fg z o Objective-C oode
5|Visual Basic|6. ab99r cde Visual Basic llso dkd
6|Ruby|1. lkd dsk Ruby kksdk

$ cat file1
Ruby
Visual Basic
Objective-C
C
C++
Basic
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...