tr not working inside function

I am new to trying to write bash functions, so maybe I’m doing something wrong, but when I execute:

cat $myfile 2>&1 | tee "cat_$(echo "$myfile" | tr . _)_$(date +%Y_%m_%d_%H%M%S).txt"

it saves a file that starts with cat_test_txt_

But when I save this function in my .bashrc:

catfile () {
  cat $1 2>&1 | tee "cat_$(echo "$1" | tr . _)_$(date +%Y_%m_%d_%H%M%S).txt";

Then execute:

catfile test.txt

It saves a file that starts with cat_test.txt_

Does anyone know why the "." is not being replaced by "_"?

Asked By: Joe


I don’t know and I can’t reproduce.

You can do typeset -f catfile to check that your function is defined as you think it is, or run (set -o xtrace; catfile test.txt) to see what it’s actually doing.

However here, if using bash, I’d rather write it:

catfile () {
  local file
  printf -v file 'cat_%s_%(%Y_%m_%d_%H%M%S)T.txt' "${1//./_}" -1
  <"$1" tee -- "$file"

Using bash‘s builtin printf for formatting and timestamp expansion and the ksh93-style ${param//pattern/replacement} parameter expansion operator to do the . -> _ substitution.

Or the zsh equivalent:

catfile() <$1 >&1 > cat_${1//./_}_${(%):-%D{%Y_%m_%d_%Y%M%S}}.txt

Here using zsh‘s internal tee when output is redirected more than once and prompt expansion (here enabled upon parameter expansion using the % parameter expansion flag) to generate the timestamp.

Some (unrelated) problems with your approach:

  • you’re using echo which can’t be used for arbitrary data
  • You forgot the quotes around $1.
  • You forgot -- before $1 to delimit options
  • UUOC.
Answered By: Stéphane Chazelas
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.