#bash #shell #unix #scripting #awk
#bash #оболочка #unix #создание сценариев #awk
Вопрос:
у меня есть небольшой файл примерно с 50 строками и 2 полями, как показано ниже
file1
-----
12345 8373
65236 7376
82738 2872
..
..
..
у меня есть около 100 файлов, которые разделены запятой ","
, как показано ниже:
file2
-----
1,3,4,4,12345,,,23,3,,,2,8373,1,1
в каждом файле много строк, похожих на приведенную выше строку.
я хочу извлечь из всех этих 100 файлов, чьи
5-е поле равнозначно 1-му полю в первом файле и
13-е поле равно 2-му полю в первом файле
Я хочу выполнить поиск по всем 100 файлам, используя этот единственный файл?
я придумал приведенный ниже вариант на случай файла, разделенного одной запятой.я даже не уверен, правильно ли это! но у меня есть несколько файлов, разделенных запятыми.
awk -F"t|," 'FNR==NR{a[$1$2] ;next}($5$13 in a)' file1 file2
кто-нибудь может мне помочь, пожалуйста?
РЕДАКТИРОВАТЬ: приведенная выше команда отлично работает в случае одного файла.
Комментарии:
1. Вы сказали: «Я даже не уверен, правильно ли это!» Если кто-нибудь здесь предоставит вам другой скрипт, как вы узнаете, он правильный?
2. Поля 1 и 5 должны совпадать, и поля 2 и 13 должны совпадать, и номера строк также должны совпадать? Другими словами, если поля совпадают, но они совпадают только в строке 1 первого файла и строке 42 второго файла, эти строки на самом деле не совпадают. Это правильно?
3. Строки могут не совпадать. Кстати, я протестировал свою команду, и она отлично работает в случае одного файла.
4. Работает ли это с несколькими файлами? Если нет, то что происходит не так? Вы получаете сообщение об ошибке?
Ответ №1:
Вот еще один вариант использования массива, позволяющий избежать нескольких рабочих файлов:
#!/bin/awk -f
FILENAME == "file1" {
keys[$1] = ""
keys[$2] = ""
next
}
{
split($0, fields, "," )
if (fields[5] in keys amp;amp; fields[13] in keys) print "*:",$0
}
Я использую split, потому что разделитель полей в двух файлах отличается. При необходимости вы можете поменять его местами. Вы должны вызвать скрипт таким образом:
runit.awk file1 file2
Альтернативой является явное открытие первого файла (с помощью «open») и чтение его (readline) в блоке BEGIN.
Ответ №2:
Вот простой подход. Извлеките каждую строку из небольшого файла, разделите его на поля, а затем используйте awk для печати строк из других файлов, которые соответствуют этим полям:
while read line
do
f1=$(echo $line | awk '{print $1}')
f2=$(echo $line | awk '{print $2}')
awk -v f1="$f1" -v f2="$f2" -F, '$5==f1 amp;amp; $13==f2' file*
done < small_file