вырезать -f несколько аргументов

У меня есть переменная ($ var), которая содержит ряд чисел, упорядоченных и разделенных запятыми. Например: 3,31,35,57,85,108,120,130,193,234,266,354,369,406,430,438,472,490,503,553,579,591,629,670,715,742,768,792,813

Мой первоначальный план состоял в том, чтобы использовать их для извлечения серии столбцов в файле1 с помощью следующего кода: cat file1 | cut -f "$var"

Терминал предупреждает меня о проблеме: слишком длинный список аргументов. Моя цель остается прежней - какой стратегии / альтернативы я могу следовать? Мне нужно что-то, что позволяет мне получить все столбцы (сохраняя их или нет в файле). Использование цикла или чего-то еще может помешать мне сделать это вручную / индивидуально.

Пример желаемого результата (меньшего размера):

123  299    429
12   0      2 
0    0      2
4    15     20
4    22     27
3    2      7
0    0      0
61   155    77
8327 5961   10023
5    11     17 
5777 8840   5669 
10   3      1 
53   365    199 
1    0      3 
26   31     15 
1    0      0

person Gero    schedule 10.02.2021    source источник
comment
Чтобы получить «слишком длинный список аргументов», должно быть много столбцов. Оболочка или cut выдает ошибку? Если это оболочка, то у вас, вероятно, более 128 КиБ аргумента в строке (для macOS потребуется более 256 КиБ). Это означает, что в файле также есть очень длинные строки. Если вместо этого он cut жалуется, то вам нужно перестроить его с любым пределом, из-за которого он генерирует сообщение, поднятое достаточно большого размера.   -  person Jonathan Leffler    schedule 10.02.2021
comment
См. Чтобы проверить состояние ошибки E2BIG в exec, код, который проверяет размер командной строки, которую вы можете использовать. Ошибка «слишком длинный список аргументов» соответствует E2BIG в <errno.h> (в коде C).   -  person Jonathan Leffler    schedule 12.02.2021


Ответы (2)


Предполагая:

  • Ваш file1 содержит огромное количество столбцов, разделенных табуляцией.
  • Вы хотите выбрать столбцы, перечисленные в переменной $ var bash.
  • Список слишком длинный, чтобы его можно было использовать в качестве аргумента командной строки.

Тогда не могли бы вы попробовать awk решение:

#!/bin/bash

var="3,31,35,57,85,108,120,130,193,234,266,354,369,406,430,438,472,490,503,553,579,591,629,670,715,742,768,792,813"
echo "$var" > list
# the "echo" command above is for the demonstration purpose only.
# please create a csv file "list" which contains the column list as "var".

awk '
    BEGIN {FS = OFS = "\t"}                     # assign the field separators to TAB
    NR==FNR {len = split($0, a, ","); next}     # read the file "list" and assign an array "a" to the list
    {
        result = $a[1]                          # 1st element of the column indexed by array a
        for (i = 2; i <= len; i++)              # loop over the column list
            result = result OFS $a[i]           # append the next element of the indexed column
        print result                            # print the record
    }
' list file1

Нам нужно сохранить список номеров столбцов в отдельном списке файлов, чтобы избежать ошибки Argument list too long. Я тестировал ок. Список 600 КБ, и он работает.

person tshiono    schedule 10.02.2021
comment
Спасибо! Оно работает :) - person Gero; 11.02.2021

Используйте awk:

awk -F, '{ print $4","$7 }' file1

В этом примере мы устанавливаем разделитель полей с -F, а затем печатаем только 4-е и 7-е поля / столбцы.

person Raman Sailopal    schedule 10.02.2021
comment
Если список слишком длинный для оболочки, то сценарий awk в командной строке тоже будет слишком длинным. В этом случае вам нужно будет создать awk код в файле (например, script.awk), а затем запустить awk -F, -f script.awk file1. - person Jonathan Leffler; 10.02.2021