Конвейер вывода grep в grep внутри bash

в bash, используяcolumn

$ column -s $'\t' -t file.tsv
col1       col2 col2 col2  col3 col3  col4
col1       col2 col2       col3       col4 col4
col1 col1  col2 col2       col3       col4 col4 col4

column -tиспользует 2 пробела для разделения столбцов


С awk я бы написал

awk -F '\t' -v cols=4 '
    NR == FNR {
        for (i=1; i<=cols; i++) 
            if (NR == 1 || length($i) > w[i]) 
                w[i] = length($i)
        next
    }
    {
        for (i=1; i<=cols; i++) 
            printf "%-*s%s", w[i], $i, (i == cols ? ORS : FS) 
    }
' file.tsv file.tsv

Где я обрабатываю файл дважды :сначала, чтобы найти максимальную ширину для каждого столбца, а затем еще раз, чтобы переформатировать файл. Я использую вкладку, чтобы разделить столбцы в выводе.

col1            col2 col2 col2  col3 col3       col4
col1            col2 col2       col3            col4 col4
col1 col1       col2 col2       col3            col4 col4 col4
2
16.07.2019, 18:37
1 ответ

Ваша идея верна, но аргумент входного файла/строки находится не в том месте. Это должно было быть написано как

grep "Gary:" "$1" | grep -v "\(said\|told\)"

, что означает применение первого выражения grepдля сопоставления всех строк, содержащих Gary, и строк фильтрации, содержащих слова saidили told.

При вашей попытке, начиная с запуска с конвейером, запускаются оба процесса grep, но часть после |обрабатывает ввод $1, как если бы это был файл, вместо того, чтобы получать ввод из стандартного ввода, а не из pipe и печатает пару строк, которые вы видите.

Но в это время вы видите, что терминал зависает, потому что первый grepвсе еще ожидает ввода в своем стандартном потоке ввода, но не видит его. Нажатие Ctrl -C отправляет сигнал SIGINT, который в конечном итоге уничтожает конвейер.

3
27.01.2020, 22:02

Теги

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