транспонировать один столбец файла CSV

Просто вставьте команду в цикл while. Здесь есть ряд нюансов, но в основном (в bash или любой оболочке POSIX):

longcommand |
  while IFS= read -r line
  do
    whatever "$line"
  done

Другая основная проблема с этим (кроме IFS ниже) - это когда вы пытаетесь использовать переменные внутри цикла после его завершения. Это происходит потому, что цикл на самом деле выполняется в под-оболочке (просто другой процесс оболочки), из которой вы не можете получить доступ к переменным (также она завершается, когда завершается цикл, и в этот момент переменные полностью исчезают. Чтобы обойти это, вы можете сделать:

longcommand | {
  while IFS= read -r line
  do
    whatever "$line"
    lastline="$line"
  done

  # This won't work without the braces.
  echo "The last line was: $lastline"
}

Пример Хауке о настройке lastpipe в bash является другим решением.

Обновление

Чтобы убедиться, что вы обрабатываете вывод команды "по мере ее выполнения", вы можете использовать stdbuf для установки stdout процесса в режим линейной буферизации.

stdbuf -oL longcommand |
  while IFS= read -r line
  do
    whatever "$line"
  done

Это настроит процесс на запись одной строки за раз в трубу вместо внутренней буферизации вывода в блоки. Имейте в виду, что программа может сама изменить эту настройку. Аналогичного эффекта можно добиться с помощью unbuffer (часть expect) или script.

stdbuf доступен в системах GNU и FreeBSD, он влияет только на stdio буферизацию и работает только для не-setuid, не-setgid приложений, которые динамически связаны (поскольку использует трюк LD_PRELOAD).

0
10.12.2018, 22:23
4 ответа

Попробуйте также

awk '
$1 != LAST      {printf "%s%s ", LD, $1         # print every new COL1 value
                 LAST = $1                      # and remeber it
                 LD = RS                        # set the line delimiter (empty at program start)
                 FD = ""                        # unset field delimiter
                }
                {printf "%s%s", FD, $2          # print successive second fields, after field delim 
                 FD = "|"                       # set the field delimiter
                }
END             {printf RS                      # last action: new line
                }
' file
FileA, CREATE|MODIFY|DELETE
FileB, CREATE|MODIFY
1
28.01.2020, 02:16
awk '1 {if (a[$1]) {a[$1] = a[$1]" "$2"|"} else {a[$1] = $2"|"}} END {for (i in a) { print i,a[i]}}' file |sed 's/.$//'
1
28.01.2020, 02:16

И четвертый :Д

awk '1 {if (a[$1]) {a[$1] = a[$1]$2"|"} else {a[$1] = $2"|"}} END {for (i in a) { print i,gensub( /\|$/,"","1",a[i])}}' kumarjit
FileA, CREATE|MODIFY|DELETE
FileB, CREATE|MODIFY
1
28.01.2020, 02:16

Для вывода в отсортированном порядке с помощью GNU awk

gawk -F', ' '
    { a[$1] = a[$1] "|" $2 }
    END {
        PROCINFO["sorted_in"] = "@ind_str_asc"
        for (b in a) print b ", " substr(a[b], 2)
    }
'

Для вывода в исходном порядке клавиш:

awk -F', ' '
    !($1 in a) { keys[++count] = $1 }
    { a[$1] = a[$1] "|" $2 }
    END {
        for (i = 1; i <= count; i++)
            print keys[i] ", " substr(a[keys[i]], 2)
    }
'
1
28.01.2020, 02:16

Теги

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