0

I have to copy a file Test_*.txt to Test_20190101_Timestamp.txt, where * is a wild card and 20190101 is the date.

cp test_*.txt test_*_"$(date +%Y%m%d-%H%M%S)".txt

When I copy the files the output copy is also coming as Test_*_Timestamp.txt. How can I copy the entire file without the wildcards?

I've also tried this, but it also failed

cp test_*.txt test*_"$(date +%Y%m%d-%H%M%S)".txt 
cp: target 'test*_20200102-160523.txt' is not a directory
Chris Davies
  • 116,213
  • 16
  • 160
  • 287

2 Answers2

1

You need to loop over the files:

for file in Test_*.txt; do
    fileroot=${file%.txt}    # remove the extension
    cp -v "$file" "${fileroot}_Timestamp.txt"
done
glenn jackman
  • 85,964
0

The problem - as you may have found out - is that you assumed in your original attempt that the actual value of the wildcard is "transferred" between the different arguments of your command (i.e. from your source filename to your intended target filename).

However, this is not how wildcard expansion (or, rather, "glob expansion") works in the shell. Rather, everywhere a wildcard appears, the shell expands this internally to a list of matching files and executes your command as if you had specified the entire list (see e.g. this tutorial on shell globbing). So, if you have files

Test_a.txt
Test_b.txt
Test_c.txt

in your directory, your cp command would actually behave as if you had typed

cp Test_a.txt Test_b.txt Test_c.txt Test_*_20200102-160523.txt

Since the last argument is taken as the destination of the copy command, and you have specified multiple source files, cp assumes this to be a directory and complains that no directory of that name exists.

Why now does it complain about there being no Test_*_20200102-160523.txt directory with a literal * in it? The standard behaviour (at least of the bash) is that if you specify a wildcard character and there is no matching file present, the wildcard character will be interpreted literally as itself - and since your expression Test_*_20200102-160523.txt was intended as target filename, it does not yet exist in the current directory.

This is the reason behind @glennjackman's answer that you need to loop over your input files to achieve the desired result.

AdminBee
  • 22,803