Reputation: 103
I have the following code:
while ...
echo -n "some text"
done | while read; do
echo "$REPLY" >> file
done
but echo works only when used without "-n" flag. looks like when using -n, the output is not flushed/read by next while loop
How can I make sure that "some text" will be read even when not followed by EOL?
Upvotes: 9
Views: 928
Reputation: 1994
The workaround would be (following original example):
while ...
echo -n "some text"
done | (cat && echo) | while read; do
echo "$REPLY" >> file
done
This will append EOL to the test stream & allow read
to read it.
The side effect will be an additional EOL at the end of stream.
Upvotes: 1
Reputation: 20002
You can make read
read one char a time, but should add something for reading special characters (newlines, spaces): IFS=
.
I want to show that I really capture the characters, so I will uppercase the replies.
i=0
while (( i++<5 )) ; do
echo -n "some text $i. "
sleep 1;
done | while IFS= read -rn1 reply; do
printf "%s" "${reply^^}"
done
This solution has one feature: You will not see any newlines. When you want to see them too, you need to fix this with
i=1
while (( i++<5 )) ; do
echo -n "some text $i.
second line."
sleep 1;
done | while IFS= read -rn1 reply; do
if (( ${#reply} == 0 )); then
echo
else
printf "%s" "${reply^^}"
fi
done
Upvotes: 0
Reputation: 971
You can't distinguish between
echo -n "some text"
and
echo -n "some t"
echo -n "ext"
so you need some kind of delimiting rule. Usually EOL is used for that. read
supports custom delimiter via -d or can split based on number of chars via -n or -N. For example you can make read
fire on each symbol:
echo -n qwe | while read -N 1 ch; do echo $ch; done
Upvotes: 4
Reputation: 97948
You can start with defining your own delimiter:
while :; do
echo -n "some text"
sleep 2
done | while read -d' ' reply; do
echo "-$reply-"
done
This prints:
-some-
-textsome-
-textsome-
For an email perhaps it makes sense to use .
as a delimiter, but you need to decide on some tokenization scheme.
Upvotes: 1