Не совсем, нет. Буферизация устанавливается для каждого процесса -с помощью вызова setbuf(3)
, языки сценариев предлагают различные степени контроля над (TCL :полным, Perl|Python|Ruby :неполным, Shell :вообще нет ). Вам нужно будет использовать оболочку, которая имитирует терминал (unbuffer, expect, tmux )или попробовать исправление непереносимых системных вызовов (stdbuf
), чтобы попытаться повлиять на то, как выполняется вывод, или добавить код в каждое приложение. так что вывод может быть установлен как небуферизованный, буферизованный по строкам или буферизованный по блокам (или любое другое подмножество из тех, что предлагает язык, если таковые имеются ). Некоторые приложения уже будут иметь для этого флаги, например. -l
из tcpdump
, или несложно добавить такой код:
#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long qw(GetOptions);
GetOptions( 'l' => \my $Flag_Unbuffer ) or exit 64;
STDOUT->autoflush(1) if $Flag_Unbuffer;
print "hi\n" for 1..4;
sleep 10;
Если это сохранить как lflag
и сделать исполняемым, разницу в поведении можно будет наблюдать, запустив:
$./lflag | cat
или
$./lflag -l | cat
Если ваши данные не слишком велики, это простое решение с квадратичной сложностью:
cat sort_keys.txt | while read key ; do egrep "^$key " file1.csv ; done
Для добавления/удаления заголовка добавьте команды head
и tail
по мере необходимости.
Просто ради добавления варианта можно запустить маршрут steeldriver , но упростить логику, отказавшись от использования как функции, так и awk
встроенного -массива, такого как как PROCINFO
. Это работает только для ключей сортировки, которые не повторяются.
$ gawk '
NR==FNR {o[$1]=FNR; next} # map keys to numerical order in 1st input file `sort_key.txt`
FNR==1 {print; next} # print header of 2nd input file `file.csv`; go to next record
{a[$1]=$0} # after header, place each record of `file.csv` in array `a`.
END {
for(i in o) b[o[i]]=i; # make new array, `b`, with swapped keys and values from array `o`.
n=length(o)
for (j=1;j<=n;j++) print a[b[j]]
}
' sort_key.txt file.csv
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
Для этого можно использовать join
. Изman join
:
For each pair of input lines with identical join fields, write a line to standard output. The default join field is the first, delimited by blanks.
Обратите внимание, что первая строка не должна быть отсортирована.
TLDR:
head -n 1 file1.csv; join -1 2 <(cat -n sort_keys.txt | sort -k 2) <(tail -n +2 file1.csv | sort) | sort -n -k 2 | awk '{ print $1, $3 }'
сделает свое дело.
Пояснения
В общем,:
Кроме того, join
необходимо отсортировать файлы.
Это приведет нас к:
cat -n sort_keys.txt | sort -k 2
3 apple
1 cat
4 cow
2 dog
tail -n +2 file1.csv | sort
apple fruit
cat animal
cow animal
dog animal
-1 2
):join -1 2 <(cat -n sort_keys.txt | sort -k 2) <(tail -n +2 file1.csv | sort)
apple 3 fruit
cat 1 animal
cow 4 animal
dog 2 animal
`... | сортировать -n -k 2 | awk '{напечатать $1, $3}'
cat animal
dog animal
apple fruit
cow animal
head -n 1 file1.csv; join -1 2 <(cat -n sort_keys.txt | sort -k 2) <(tail -n +2 file1.csv | sort) | sort -n -k 2 | awk '{ print $1, $3 }'
COLUMN1 COlUMN2
cat animal
dog animal
apple fruit
cow animal
Идем дальше
В зависимости от ваших реальных данных вам придется настроить номера полей и разделитель полей.
Вы также можете сохранить строки данных, ключ которых не находится в ключах сортировки _, и/или сохранить строки ключей сортировки _, не имеющих соответствующих строк данных (см. -a
вариант соединения ).
Приятного использования join
!