Канал в несколько файлов в оболочке

В emacs исследовать

clipboard-kill-region
clipboard-kill-ring-save
clipboard-yank

Я записал это для копирования целого буфера в буфер обмена:

(defun copy-all ()
  "copy buffer to clipboard"
  (interactive)
  (clipboard-kill-ring-save (point-min) (point-max))
  (message "Copy done.") )

Кроме того, я сделал полезный псевдоним названным xc, как это: xclip -selection clipboard. Затем echo $(pwd) | xc (например), отправит Ваше положение дерева каталогов в буфер обмена.

И, случайно, я заметил, что могу вставить в urxvt путем нажатия mousewheel кнопки. Мне не нравится использовать мышь вообще, поэтому если Вы знаете, как связать это с сочетанием клавиш, скажите мне.

Править: Я нашел (где-нибудь на этом сайте), что ответ на финал, который (мой) вопрос - он уже сделан, а именно, Shift-Insert.

29
10.01.2018, 13:53
6 ответов

Если у Вас есть мишень

./app | tee >(grep A > A.out) >(grep B > B.out) >(grep C > C.out) > /dev/null

(отсюда)

(о замене процесса)

78
27.01.2020, 19:38
  • 1
    Потрясающий, это могло также быть представлено как: ./app | tee >(grep A > A.out) >(grep B > B.out) | grep C > C.out –  evilsoup 26.10.2013, 21:13
  • 2
    Этот ответ в настоящее время является единственным точным, учитывая оригинальное название вопроса "канал к нескольким процессам". –  acelent 26.10.2013, 21:52
  • 3
    +1. Это - самый обычно применимый ответ, так как он не зависит от того, что определенная команда фильтрации была grep. –  ruakh 26.10.2013, 22:43
  • 4
    я согласился бы, что это - лучший ответ для поставленного вопроса и должно быть отмечено так. Параллель является другим решением (как отправлено), но сделавший некоторые синхронизированные сравнения вышеупомянутый пример более эффективен. Если op вместо этого включил высоко интенсивные действия CPU, такие как несколько, регистрируют сжатие или несколько mp3 преобразование затем несомненно, параллельное решение должно оказаться более эффективным. –  AsymLabs 28.10.2013, 19:01

Можно использовать awk

./app | awk '/A/{ print > "A.out"}; /B/{ print > "B.out"}; /C/{ print > "C.out"}'
32
27.01.2020, 19:38
  • 1
    Заголовок вопроса является каналом к нескольким процессам, этот ответ о "передаче по каналу" (диспетчеризирующий regex) в несколько файлов. Так как этот ответ был принят, заголовок вопроса должен быть изменен соответственно. –  acelent 26.10.2013, 21:50
  • 2
    @PauloMadeira Вы правы. То, что Вы думаете, было бы лучшим заголовком? –  sj755 26.10.2013, 21:58
  • 3
    я предложил очень маленькое редактирование "Канал нескольким файлам в оболочке", это ожидает пересмотр, проверяет его. Я ожидал удалять комментарий, если он был принят. –  acelent 26.10.2013, 22:05
  • 4
    @PauloMadeira - Я изменил заголовок. Не видел Ваше редактирование, но Вы корректны, использование процессов в заголовке было неправильным, если это - принятый ответ. –  slm♦ 27.10.2013, 00:21

Вы могли также использовать способности к сопоставлению с образцом своей оболочки:

./app | while read line; do 
     [[ "$line" =~ A ]] && echo $line >> A.out; 
     [[ "$line" =~ B ]] && echo $line >> B.out; 
     [[ "$line" =~ C ]] && echo $line >> C.out; 
 done

Или даже:

./app | while read line; do for foo in A B C; do 
     [[ "$line" =~ "$foo" ]] && echo $line >> "$foo".out; 
  done; done

Более безопасный путь, который может иметь дело с обратными косыми чертами и строками, запускающимися с -:

./app | while IFS= read -r line; do for foo in A B C; do 
     [[ "$line" =~ "$foo" ]] && printf -- "$line\n" >> "$foo".out; 
  done; done

Как @StephaneChazelas указывает в комментариях, это не очень эффективно. Лучшее решение, вероятно, @AurélienOoms'.

17
27.01.2020, 19:38
  • 1
    Это предполагает, что вход не содержит обратные косые черты или пробелы или подстановочные символы или строки, которые запускаются с -n, -e... Это также будет ужасно неэффективным, поскольку это означает несколько системных вызовов на строку (один read(2) на символ, при этом файл открыт, пишущий закрытый для каждой строки...). Обычно использование while read циклы к тексту процесса в оболочках являются плохой практикой. –  Stéphane Chazelas 27.10.2013, 10:55
  • 2
    @StephaneChazelas я отредактировал свой ответ. Это должно работать с обратными косыми чертами и -n и т.д. теперь. Насколько я могу сказать обе работы версий хорошо с пробелами, хотя, я неправильно? –  terdon♦ 27.10.2013, 16:37
  • 3
    Нет, первый аргумент printf формат. Нет никакой причины отъезда Вас, переменные закрыли кавычки там. –  Stéphane Chazelas 27.10.2013, 22:39
  • 4
    Это также прервет удар (и другие оболочки, которые используют cstrings похожим способом), если существуют пустые указатели во входе. –  Chris Down 28.10.2013, 11:38

Если у Вас есть несколько ядер, и Вы хотите, чтобы процессы были параллельно, можно сделать:

parallel -j 3 -- './app | grep A > A.out' './app | grep B > B.out' './app | grep C > C.out'

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

Параллель утилиты гну от Ole Tange может быть получена из большей части repos под именем параллель или moreutils. Источник может быть получен из Savannah.gnu.org. Также вводное учебное видео здесь.

Приложение

Используя более позднюю версию параллели (не обязательно версия в Вашем распределении repo), можно использовать более изящную конструкцию:

./app | parallel -j3 -k --pipe 'grep {1} >> {1}.log' ::: 'A' 'B' 'C'

Который достигает результата выполнения одного./приложения и 3 параллелей grep процессы в отдельных ядрах или потоках (как определено самой параллелью, также полагайте, что-j3 является дополнительным, но это предоставляется в этом примере в поучительных целях).

Более новая версия параллели может быть получена путем выполнения:

wget http://ftpmirror.gnu.org/parallel/parallel-20131022.tar.bz2

Затем обычные распаковывают, CD, чтобы быть параллельными - {дата}./настр && делают, sudo делают установку. Это установит параллель, страница справочника параллельная и страница справочника parallel_tutorial.

9
27.01.2020, 19:38

Вот один в Perl:

./app | perl -ne 'BEGIN {open(FDA, ">A.out") and 
                         open(FDB, ">B.out") and 
                         open(FDC, ">C.out") or die("Cannot open files: $!\n")} 
                  print FDA $_ if /A/; print FDB $_ if /B/; print FDC $_ if /C/'
7
27.01.2020, 19:38
sed -ne/A/w\ A.out -e/B/w\ B.out -e/C/p <in >C.out

...если доступен для чтения, то все три outfiles будут усечены, прежде чем в них что-либо будет записано.

1
29.04.2021, 00:45

Теги

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