Предлагаю вам воспользоваться моим новым инструментом websocat .
echo "Some data to be sent" | websocat ws://server/url
Очевидно, что существуют также альтернативы, такие как wscat (golang)или wscat (node).
Я не знаю, как это сделать, используя только sort
,но вы можете «свернуть» значения, например, с помощью awk, а затем отсортировать:
$ awk -F'\t' '
BEGIN{OFS=FS}
{k = $1 FS $2}
{a[k] = a[k] == "" ? $3 : a[k] "," $3}
END{for (k in a) print k,a[k]}
' file | sort
a b hello,goodbye
a c I say
g g test
В последней версии GNU awk вы можете избежать внешней сортировки, установив порядок обхода массива с помощьюPROCINFO
:
awk -F'\t' '
BEGIN{OFS=FS}
{k = $1 FS $2}
{a[k] = a[k] == "" ? $3 : a[k] "," $3}
END{PROCINFO["sorted_in"]="@ind_str_asc"; for (k in a) print k,a[k]}
' file
В качестве альтернативы, с помощью массива данных GNU
datamash groupby 1,2 collapse 3 <file
или более подробно (, но более гибко )с Миллером
mlr --nidx --fs tab nest --implode --values --across-records --nested-fs, -f 3 file
Двухэтапное -решение в bash, использующее временные файлы:
$ cat table.csv
a b hello
a b goodbye
g g test
a c I say
$ WD=$(mktemp -d) ; while read K1 K2 V ; do echo -n ",$V" >>$WD/$K1:$K2 ; done <table.csv
$ sort -k1,1 -k2,2 -u table.csv | while read K1 K2 V ; do echo $K1 $K2 $(sed 's/^.//' <$WD/$K1:$K2) ; done
a b hello,goodbye
a c I say
g g test
Суть этого решения заключается в использовании перенаправления добавления в оболочке(>>
)для сбора значений для ключей, которые равны перед сортировкой.
Это также можно сделать с помощью sed
функции (извините, это не совсем по-человечески -читабельно):
echo "a b hello
a c goodbye
g g foo
a c bar
a b test
a c I say" | sort -k1,1 -k2,2 | sed ":a N; s/\([^\t]*\)\t\([^\t]*\)\t\([^\t]*\)\n\1\t\2\t\([^\t]*\)/\1\t\2\t\3,\4/; ta; P; D; ba;"
И вывод, как и ожидалось:
a b hello,test
a c bar,goodbye,I say
g g foo
sed
вместо uniq
. N;
попросит sed
работать на 2-х строках (или «еще одну строку» )вместо 1. s/.../.../
объединит две строки. \([^\t]*\)
займет столбец (как можно больше символов, но не\t
). \t
— разделитель табуляции (). \n\t\1\t\2\t
проверяет, есть ли у нас вторая строка с двумя похожими первыми столбцами. /\1\t\2\t\3,\4/
преобразует 2 строки в одну с одинаковыми первым и вторым столбцами, а третий столбец объединяется. :a... ta;
похоже на цикл while
(сделать это снова, пока s
замена работала ). P; D;
если мы здесь, то s
не удалось, поэтому у нас есть две «разные» (в первой или второй колонке )строк в пространстве шаблонов. P
печатает первую строку (с возможными объединенными строками ), а D
удаляет строку, которую мы напечатали. ba;
зацикливается, пока он может читать строки (с 1 строкой в пространстве шаблонов ).