Является ли разделение потока из bash переносимым на другие языки?

От разделение потока Я имею в виду способность:

  1. фильтровать содержимое потока по первой функции
  2. одна часть потока обрабатывается второй функцией
  3. остальная часть потока обрабатывается третьей функцией
  4. поток никогда не сохраняется (на лету)

Пример иногда лучше длинного объяснения. Эта командная строка используется tee а также процесс замены разделить поток:

$> cut -f2 file | tee >( grep "AB" | sort | ... ) | grep -v "AB" | tr A B | ...

В этом примере поток разделен на две части: строки, содержащие "AB" и остальное:

cut -f2 file ---->- line contains "AB" ->- sort ->- ...
\--->- does not contain "AB" ->- tr A B ->- ...

Но мне не нравится этот метод разделения потока, потому что поток сначала дублируется ( tee) затем дважды отфильтровать grep а также grep -v).

Поэтому мне интересно, если что-то вроде разделение потока доступно на других языках как , , ,

Ниже приведен более сложный пример.


Сложный bash разделение потока

counter.sh разбивает поток на три части (начало, середина и конец). И для каждого раздела поток снова разделяется для подсчета появления символов <, | а также >:

#!/bin/bash
{
{  tee >( sed -n '1,/^--$/!p' >&3 ) |
sed -n '1,/^--$/p'        |
tee >( echo "del at begin:  $(grep -c '<')"    >&4 ) |
tee >( echo "add at begin:  $(grep -c '>')"    >&4 ) |
{ echo "chg at begin:  $(grep -c '|')"; } >&4
}  3>&1 1>&2  |
{  tee >( sed -n '/^--$/,/^--$/!p' >&3 ) |
sed -n '/^--$/,/^--$/p'        |
tee >( echo "del at end:    $(grep -c '<')"    >&4 ) |
tee >( echo "add at end:    $(grep -c '>')"    >&4 ) |
{ echo "chg at end:    $(grep -c '|')"; } >&4
}  3>&1 1>&2 |
tee >( echo "del in middle: $(grep -c '<')"    >&4 ) |
tee >( echo "add in middle: $(grep -c '>')"    >&4 ) |
echo "chg in middle: $(grep -c '|')";
} 4>&1

Этот скрипт используется для подсчета количества добавленных / измененных / удаленных строк в разделах begin / middle / end. Ввод этого скрипта является потоком:

$> cat file-A
1
22
3
4
5
6
77
8

$> cat file-B
22
3
4
42
6
77
8
99

$> diff --side-by-side file-A file-B | egrep -1 '<|\||>' | ./counter.sh
del at begin:  1
add at begin:  0
chg at begin:  0
del at end:    0
add at end:    1
chg at end:    0
del in middle: 0
add in middle: 0
chg in middle: 1

Как эффективно реализовать такое counter.sh на других языках программирования без сохранения данных во временном буфере?


Ответ

Как отмечено Леннарт Регебро, я накручивание этот вопрос. Конечно, все эти языки могут разделять входные потоки в ответ на ysth. В псевдокоде:

while input-stream
{
case (begin section)
{
case (symbol <) aB++
case (symbol |) cB++
case (symbol >) dB++
}
case (middle section)
{
case (symbol <) aM++
case (symbol |) cM++
case (symbol >) dM++
}
case (ending section)
{
case (symbol <) aE++
case (symbol |) cE++
case (symbol >) dE++
}
}

PrintResult (aB, cB, dB, aM, cM, dM, aE, cE, dE)

Заключение: Разделение потока лучше сделать в python/perl/awk/C++ чем с помощью tee + процесс замены.

2

Решение

Любой из упомянутых вами языков идеально подходит для этого.

В Perl я бы не использовал команду diff, я бы просто использовал АЛГОРИТМ :: Diff на оригинальные файлы.

1

Другие решения

Tee — это просто программа на C, использующая базовые системные вызовы, вы можете реализовать ее на любом языке, который обеспечивает доступ к системным библиотекам.

Поиск в Google для

чай на моем любимом языке

должен найти все ответы, которые вам нужны.

1

По вопросам рекламы [email protected]