У меня есть список номеров.
Для каждого числа я хочу найти его в другом файле.
Но я хочу найти его только в 12-м столбце.
Я пробовал много вещей, включая внедрение переменных:
for line in `cat numbers.txt`; do awk -F'|' -v "LINE=$line" '$12~/LINE/' bigfilewithcolumns.txt; done
Возможно ли это с awk?
Не уверен, но пробовали ли вы $12~LINE
, как здесь stackoverflow.com/questions/11534173/…
Ой! это работает: for line in `cat numbers.txt`; do awk -F'|' -v "LINE=$line" '$12~LINE' bigfilewithcolumns.txt; done
. Итак, только '$12~LINE'
, обратной косой черты здесь нет. Спасибо!
пожалуйста, обновите вопрос, используя образцы (3-6 строк) из обоих файлов вместе с ожидаемыми результатами; использование цикла bash
для многократного сканирования большого файла будет работать плохо; то, что вы описываете, вероятно, (относительно) легко с помощью сценария awk
, который выполняет один проход через большой файл (таким образом, с гораздо большей производительностью) ... но нам нужны примеры ваших файлов, чтобы предоставить полезное решение
Это условие
$12~/LINE/
проверяет, есть ли LINE
где-нибудь в столбце номер 12. Также использование регулярного выражения для работы с числом может привести к совпадению для разных чисел, например.
$12~/234/
будет верно не только для 234, но и для 1234, и для 2345, и для 12345, и так далее. Вам следует использовать ==
равно, если вы хотите ограничить число, равное этому. Я бы улучшил ваш код следующим образом
for line in `cat numbers.txt`
do
awk -F'|' -v LINE = "$line" '$12==LINE' bigfilewithcolumns.txt
done
ОП не знает, почему мы не читаем строки с, но, вероятно, вам следует.
Вы не хотите вызывать отдельный awk для каждой строки в числовом файле. awk может обрабатывать несколько файлов:
awk -F'|' '
NR == FNR { # this condition is only true for the first file
num[$0] = 1
next
}
$12 in num
' numbers.txt bigfilewithcolumns.txt
awk
, вероятно, подходящий для этого инструмент. Для полноты картины: если количество столбцов в bigfilewithcolumns.txt
известно и постоянно, и поскольку вас явно не волнует порядок вывода, это также может быть работой для join
. Если ваша оболочка bash
:
a=( 2.{1..N} )
join -t '|' -o "${a[*]}" -2 12 <( sort numbers.txt ) <( sort -t '|' -k12 bigfilewithcolumns.txt )
где N
— количество столбцов в bigfilewithcolumns.txt
. Если ваша оболочка не bash
, вам нужно будет найти другой способ передать опцию -o 2.1,2.2,...,2.N
в join
.
Если ваш join
— GNU join
, вы можете немного упростить:
join -t '|' -o 2.{1..N} -2 12 <( sort numbers.txt ) <( sort -t '|' -k12 bigfilewithcolumns.txt )
-o
в присоединении меня всегда раздражало. Использование расширения скобок оболочки — это великолепно!
Спасибо, но не используйте версию с sort -n
, это неправильно, и я только что исправил свой ответ, удалив опции -n
: join
ожидает обычную сортировку, а не числовую.
умно, но не переносимо: «Приложение должно гарантировать, что список представляет собой один аргумент командной строки», но printf "(%s)\n" 2.{1..3}
@jhnc К сожалению, ты прав, это не POSIX. -o $(printf "%s," 2.{1..11})2.12
, но менее элегантно.
ты нашел хороший компромисс
Какой макет у файла? Каково определение «12-го» столбца: вы имеете в виду столбец, определяемый пользователем, или 12-й символ в любой/каждой строке? Можете ли вы экспортировать файл в формате CSV или JSON?