2

I'm trying to write a program that takes a file's name, and puts the date on it. So I'm trying to get substrings for the filename itself, and the extension.

I'm new to BASH so maybe I'm missing something here, but following online guides, it seems like this should work-

#!/bin/bash

echo "Type filename in this dir"
read filename
file=`filename%.*`
end=`filename##*.`
today=`date +%d-%m-%y`
dated="${file}_${today}.${end}"
cat $filename > $dated

But the computer returns these errors-

./fileDater.sh: line 5: filename%.*: command not found
./fileDater.sh: line 6: filename##*.: command not found

I'm using an Ubuntu Subsystem on Windows 10, if that's important.

  • Aside from the use of backticks, `cat $filename > $dated` is probably better written as `cp "$filename" "$dated"`. Your `cat` relies on the shell to create the output file, whereas `cp` does everything itself. Note also the double quotes around filename variables, safer in case of embedded whitespace. – cdarke Jun 17 '18 at 07:22
  • Thanks for the suggestion! But I'm not completely sure what you mean by "relying on the shell", could you maybe explain what that means / how that differs from cp? – Naman Goyal Jun 17 '18 at 18:16
  • The redirection `>` and output file creation is done by the shell. When the shell creates the `cat` process it sets its `stdout` stream to point at the output file that the shell created. With `cp`, the `cp` program does everything itself. With `cp` we can control the attributes of the output file through command-line options, using the shell and `>` we just get the defaults. – cdarke Jun 18 '18 at 18:37

1 Answers1

2

It seems you've got some confusion about bash substitution; You're trying to execute a command sub-shell instead (eg. `variable##*.`) — it should be using ${ ... } .

#!/bin/bash

echo "Type filename in this dir"
read -r filename
file=${filename%.*}
end=${filename##*.}
today=$(date +%d-%m-%y)
dated="${file}_${today}.${end}"
cat "$filename" > "$dated"

I haven't tried your script, although I believe that is your main issue.


EDIT: Regarding the use of backticks (`...`)

In the form of `COMMAND` it's more or less obsolete for Bash, since it has some trouble with nesting ("inner" backticks need to be escaped) and escaping characters.

Use $(COMMAND) instead — it's also POSIX!

Bash Hackers Wiki - Command Substitution

l'L'l
  • 44,951
  • 10
  • 95
  • 146