2

Is there are way to use STDIN in a bash function?

e.g.

# echo "somevar = (100)" >> test.txt
# grep -Eo "\([[:digit:]]+\)$" test.txt
(100)

So that's fine I've got my number, next I want to remove the brackets. What I did was:

string=`grep -Eo "\([[:digit:]]+\)$" test.txt`; echo ${string:1:-1}
100

So my problem was solved, but what I spent a long time doing was:

grep -Eo "\([[:digit:]]+\)$" test.txt | echo ${$1:1:-1}
grep -Eo "\([[:digit:]]+\)$" test.txt | ${$1:1:-1}
grep -Eo "\([[:digit:]]+\)$" test.txt | xargs echo ${:1:-1}
grep -Eo "\([[:digit:]]+\)$" test.txt | xargs -I 's' echo ${s:1:-1}

etc, etc ... none of which work.

So assuming it is possible, how do I use the piped in value in the bash command?

3
  • It's not clear what you intend the syntax you're writing to do/mean. Commented Oct 9, 2017 at 17:17
  • ...that said, for a general discussion of reading an input stream for native use by shell, see BashFAQ #1 -- and BashFAQ #24 for discussion of a common caveat. Commented Oct 9, 2017 at 17:21
  • I want know if I could achieve the same as the working example using a pipe rather than storing it in a variable. Though your links to the BashFAQ seem to answer my question.
    – Martin
    Commented Oct 10, 2017 at 8:53

2 Answers 2

1

Assuming that you want to use some input from a pipe and that each line of input is to be processed separately, you could try:

echo "somevar = (100)" | grep -Eo "\([[:digit:]]+\)$" | while read in
do
  echo $in
done

The while loop will use the read command to read one line at a time in the variable IN. Within the loop you may do any treatment you need. In this case I have used an echo to show that you get the input value back.

4
  • This particular formulation is vulnerable to BashFAQ #24. Commented Oct 9, 2017 at 17:18
  • (btw, all-caps variable names are used for variables with meaning to the OS or shell, whereas names with at least one lowercase character are reserved for application use -- see pubs.opengroup.org/onlinepubs/9699919799/basedefs/…, fourth paragraph; thus, better to while read line -- or while IFS= read -r line, if you don't want to mangle backslashes or leading/trailing whitespace). Commented Oct 9, 2017 at 17:20
  • @Charles Duffy states that the IN variable will not be available outside of the loop, but it is good if used within. I have also changed it to lower case as suggested. Commented Oct 9, 2017 at 17:22
  • A little more verbose than I was hoping (secretly I thought a perl-esq $_ might exist in bash) but it does exactly what I was asking for, Thanks also to Charles Duffy, you clearly know your Bash!
    – Martin
    Commented Oct 10, 2017 at 9:02
0

The syntax you're using is for variables. Saving grep's output in variable is the natural way to use it.

If you want to use a pipeline you need to use something that modifies stdin, rather than a variable. Consider sed.

grep -Eo "\([[:digit:]]+\)$" test.txt | sed 's/^(\|)$//g'

Not the answer you're looking for? Browse other questions tagged or ask your own question.