0
EMPTY_VAR=''
MMDDYYYY='6.18.1997'
PIPE_VAR=' | xargs echo "1+" | bc'
echo "$MMDDYYYY" | cut -d "." -f 2${EMPTY_VAR}
>> 18

Command above would give me correct output, which is 18, but if I try to use PIPE_VAR instead it would give me bunch of errors:

echo "$MMDDYYYY" | cut -d "." -f 2${PIPE_VAR}
cut: '|': No such file or directory
cut: xargs: No such file or directory
cut: echo: No such file or directory
cut: '"1+"': No such file or directory
cut: '|': No such file or directory
cut: bc: No such file or directory

OR:

echo "$MMDDYYYY" | cut -d "." -f 2"$PIPE_VAR"
cut: invalid field value ‘| xargs echo "1+" | bc’
Try 'cut --help' for more information.

What I'm really trying to find out is that even possible to combine commands like this?

  • 2
    This is discussed in [I'm trying to put a command in a variable, but the complex cases always fail!](https://mywiki.wooledge.org/BashFAQ/050) – glenn jackman Nov 03 '22 at 16:39
  • @glennjackman Thanks for the info! I've tried option #3 which seems like my case, but it doesn't work either. `echo "$MMDDYYYY" | cut -d "." -f 2 ${SET_VAR:+"| xargs echo 1+ | bc"} >>cut: '| xargs echo 1+ | bc': No such file or directory` I'm definitely doing something wrong. – Evgeniy Pozdnyakov Nov 03 '22 at 17:05
  • 1
    `|` only works when it's syntax. Expansion results are never syntax; they're always data. – Charles Duffy Nov 03 '22 at 17:41
  • 1
    Section #3 in BashFAQ #50 explicitly says it's only for "options". A `|` is not an option. – Charles Duffy Nov 03 '22 at 17:42

2 Answers2

3

You can't put control operators like | in a variable, at least not without resorting to something like eval. Syntax parsing comes before parameter expansion when evaluating the command line, so Bash is only ever going to see that | as a literal character and not pipeline syntax. See BashParsing for more details.

Conditionally adding a pipeline is hard to do well, but having a part of the pipeline conditionally execute one command or another is more straightforward. It might look something like this:

#!/bin/bash
MMDDYYYY='6.18.1997'

echo "$MMDDYYYY" | cut -d "." -f 2 |
if some_conditional_command ; then
  xargs echo "1+" | bc
else
  cat
fi
tjm3772
  • 2,346
  • 2
  • 10
2

It looks like you're trying to calculate the next day. That's hard to do with plain arithmetic, particularly with month/year ends.

Let date do the work. This is GNU date. It can't parse 6.18.1997 but it can parse 6/18/1997

for MMDDYYYY in '2.28.1996' '2.28.1997'; do
  date_with_slashes=${MMDDYYYY//./\/}
  next_day=$(date -d "$date_with_slashes + 1 day" '+%-m.%-d.%Y')
  echo "$next_day"
done
2.29.1996
3.1.1997
glenn jackman
  • 238,783
  • 38
  • 220
  • 352