Использование процесса замены Bash с циклом tee и while - PullRequest
0 голосов
/ 06 января 2019

Я хочу использовать вложенный процесс подстановки с тройником в цикле while.

while read line; do
  #process line
  echo "--$line"
done < <(cat sample.file | tee >(grep "SPECLINE") | grep "LINESTOPROCESS")

Поэтому мне нужно:

  • все строки в sample.file, которые содержат выражение «LINETOPROCESS», должны быть переданы в цикл, и они будут напечатаны с префиксом «-».
  • все строки, содержащие «SPECLINE», должны быть напечатаны при первой замене процесса (в grep).

Я хочу не повторять образец. Файл более одного раза, так как он слишком большой и тяжелый.

С простым файлом sample.test:

line1 SPECLINE
line2 LINETOPROCESS
line3 LINETOPROCESS
line4 SPECLINE
line5 I don't need it
line6 also not
line7 also not
line8 SPECLINE
line9 LINETOPROCESS

Мой результат:

# ./test.sh
#

Мой желаемый результат:

# ./test.sh
line1 SPECLINE 
--line2 LINETOPROCESS
--line3 LINETOPROCESS
line4 SPECLINE
line8 SPECLINE
--line9 LINETOPROCESS

Или я также могу принять это как вывод:

# ./test.sh
--line2 LINETOPROCESS
--line3 LINETOPROCESS
--line9 LINETOPROCESS
line1 SPECLINE 
line4 SPECLINE
line8 SPECLINE

Update1

greps предназначены только для демонстрации. Мне действительно нужны эти 2 замены.

  • sample.file - это файл http.
  • grep "SPECLINE" будет "hxselect -i -s ';' -c 'div.hour'
  • grep "LINESTOPROCESS" будет "hxselect -i -s ';' -c 'div.otherclass' | hxpipe

hx программы не ориентированы на строки. Они читают из стандартного ввода и выводят в стандартный вывод.

Поэтому первая команда тройника выберет div с классом 'hour' и отделит их с помощью ';'. После этого труба после тройника выберет все div с классом 'otherclass', а hxpipe сгладит его для цикла для дальнейшей обработки.

Ответы [ 3 ]

0 голосов
/ 06 января 2019

Далее просто перебирает весь файл и просто печатает соответствующие строки. Все остальные строки игнорируются.

while read line; do
    case "$line" in
        *SPECLINE*) echo "$line" ;;
        *LINETOPROCESS*) echo "--$line" ;;
    esac
done < sample.file
0 голосов
/ 07 января 2019

Если вы хотите tee, вы можете сделать 2 изменения.
Ваш тестовый код greps LINE S TOPROCESS, ввод LINETO .. ​​
Подстановка выходного процесса дает такие проблемы, как объяснено https://stackoverflow.com/a/42766913/3220113 Вы можете сделать это по-другому.

while IFS= read -r line; do
  #process line
  echo "--$line"
done < x2 |
tee >(grep "SPECLINE") >(grep "LINETOPROCESS") >/dev/null

Я не знаю hxselect, но, похоже, он работает с полным правильно сформированным XML-документом, поэтому избегайте grep.

0 голосов
/ 06 января 2019

Я бы вообще не использовал подстановку процессов.

while IFS= read -r line; do
  if [[ $line = *SPECLINE* ]]; then
    printf '%s\n' "$line"
  elif [[ $line = *LINETOPROCESS* ]]; then
    printf '--%s\n' "$line"
  fi
done < sample.txt

Вы уже оплачиваете стоимость чтения входного потока построчно в bash; нет причин добавлять к нему служебные данные двух отдельных grep процессов.

Один awk процесс будет еще лучше, поскольку он более эффективен, чем bash метод чтения по одному символу за раз для чтения строк текста.

awk '/SPECLINE/ {print} /LINETOPROCESS/ {print "--"$0}' sample.txt

(что является слишком простым, если одна строка может совпадать с SPECLINE и LINETOPROCESS, но я оставляю это в качестве упражнения для читателя, чтобы исправить.)

...