awk
для строк после (, но не включая )первое совпадение с шаблоном Если строка, содержащая триггерный шаблон, эквивалентна «CUT HERE», вы можете опустить ее в распечатке:
echoer | awk 'flag ; /pattern/ { flag=1 }'
Каждая строка ввода проходит через два компонента кода awk. Первый компонент — flag
, который awk интерпретирует как «вывести строку, если переменная flag
не равна нулю». Поскольку переменные awk по умолчанию равны 0, изначально ничего не будет напечатано.
Второй компонент, /pattern/ { flag=1 }
, устанавливает флаг в 1, как только обнаруживает шаблон, и флаг сохраняет это значение до конца выполнения.
К тому времени, когда шаблон впервые обнаружен, возможность напечатать эту строку ввода уже упущена. Любые последующие строки (, включая дополнительные строки, содержащие шаблон ), будут напечатаны.
read
читает со стандартного ввода, поэтому оба этих read
будут считываться с вывода echo
через тот же канал, открытый на их стандартном вводе.
Чтобы read
внутри цикла считывалось со стандартного ввода вне канала, вы можете сделать:
foo () {
printf 'a\nb\nc\n' |
while IFS= read -r conflicted_file; do
printf '%s\n' "$conflicted_file"
while true; do
IFS= read <&3 -re -p "> " yn
case $yn in
[nN]* ) echo "success"; break;;
[yY]* ) echo "fail"; break;;
* ) echo "invalid input";;
esac
done
done
} 3<&0
То есть продублировать его на fd 3 для всего тела функции foo
.
Операция «чтение» пытается читать из канала вместо tty. Есть несколько решений для этого.
read... </dev/tty
. Это работает до тех пор, пока не ожидается, что ваша функция foo ()будет иметь перенаправленный ввод. Перенаправить канал на другой файловый дескриптор и зациклить его чтение, чтобы не повлиять на внутренний вызов чтения.
Что-то вроде:
exec 3< <(echo "a\nb\nc")
while read -u 3 conflicted_file; do
...
read -e -p "> " yn
...
done
exec 3>&-