Проблема, извлекающая данные из файла с помощью awk

Я имею большой файл данных и хочу разделить его на меньшие файлы на основе значений в столбце 1. Например, столбец 1 имеет числа от 1 до 10 десять раз для создания 100 строк, и я хочу все строки с номерами '1' или '2' или '3' и т.д. в их собственном файле (предпочтительно, не сортируя). Также я не хочу работать, времена команды 10 так хотели бы за него быть в цикле.

Мои файлы похожи на это:

  • text.txt

    enter image description here

  • ID.txt

    1
    2
    3
    4
    

Команда я попробовал:

cat ID.txt | while read line; do awk '$1 == ${line}' test.txt >$line.txt;done

Таким образом для суммирования я хочу, чтобы это считало значение из файла ID.txt, например, '1' и затем извлекло все строки с '1' в первой строке и поместило его в файл, названный 1.txt, затем это выполняет итерации к 2 затем 3 затем 4 и т.д.

Но так или иначе '1$ == $ {строка}' первая часть думают, не работает

1
задан 21 October 2015 в 16:34

1 ответ

Вы ищете -v опция к awk:

   -v var=val
   --assign var=val
          Assign the value val to the variable var,  before  execution  of
          the  program  begins.  Such variable values are available to the
          BEGIN rule of an AWK program.

Что-то вроде этого:

cat ID.txt | 
    while read line; do awk -vline="$line" '$1 == l' test.txt >"$line".txt;done

Который был бы лучше выражен как (предотвращение бесполезного использования кошки):

while read line; do 
    awk -vline="$line" '$1 == l' test.txt >"$line".txt;
done < ID.txt

Однако это очень медленно и неэффективно. Вы работаете awk команда на всем test.txt для каждой строки ID.txt. Почему не просто чтение ID.txt в awk самостоятельно и печать согласующие отрезки длинной линии:

awk 'NR==FNR{a[$1]++; next} ($1 in a){print >> $1".txt"}' ID.txt test.txt 

Вышеупомянутое сохраняет 1-е поле ID.txt в массиве a. NR и FNR являются особенными awk переменные, означающие "текущую строку входного потока" и "текущую строку текущего файла". Эти два только будут равны друг другу, когда первый файл будет считан. Поэтому NR==FNR{a[$1]++; next} будет только выполнен на строках первого файла. Вторая часть не будет выполняться потому что next говорит awk пропускать к следующей строке.

Вторая часть, проверки, если 1-е поле текущей строки (помнят, это только выполняется на втором файле) существует в массиве a (что означает, что это было в ID.txt) и, если это делает, печатает строку в файл под названием "field1.txt"

4
ответ дан 3 December 2019 в 07:00

Другие вопросы по тегам:

Похожие вопросы: