Adding Timestamp to a Filename with Mv in Bash

Adding timestamp to a filename with mv in BASH

The few lines you posted from your script look okay to me. It's probably something a bit deeper.

You need to find which line is giving you this error. Add set -xv to the top of your script. This will print out the line number and the command that's being executed to STDERR. This will help you identify where in your script you're getting this particular error.

BTW, do you have a shebang at the top of your script? When I see something like this, I normally expect its an issue with the Shebang. For example, if you had #! /bin/bash on top, but your bash interpreter is located in /usr/bin/bash, you'll see this error.

EDIT

New question: How can I save the file correctly in the first place, to avoid having to perform this fix every time I resend the file?

Two ways:

  1. Select the Edit->EOL Conversion->Unix Format menu item when you edit a file. Once it has the correct line endings, Notepad++ will keep them.
  2. To make sure all new files have the correct line endings, go to the Settings->Preferences menu item, and pull up the Preferences dialog box. Select the New Document/Default Directory tab. Under New Document and Format, select the Unix radio button. Click the Close button.

Bash alias create file with current timestamp in filename

Use single quotes to prevent immediate expansion.

alias unix='echo $(date +%s)'

Update: While I'm happy to have been able to explain the different expansion behavior between single and double quotes, please also see the other answer, by Robby Cornelissen, for a more efficient way to get the same result. The echo is unnecessary here since it only outputs what date already would output by itself. Therefore, date doesn't need to be run in a subshell.

Append date/timestamp to existing files

I would use a "for" loop over the wildcard list of matches and then use parameter expansion and command substitution to splice out the rest:

for file in *.log
do
echo mv -- "$file" "${file%.log}_$(date +%Y%m%d).log"
done

The pieces in the middle break down as:

  • mv -- -- invoke "mv" and explicitly tell it that there are no more options; this insulates us from filenames that might start with -i, for example
  • "${file%.log} -- expands the "$file" variable and removes the ".log" from the end
  • _ -- just adds the underscore where we want it
  • $(date +%Y%m%d) -- calls out to the date command and inserts the resulting output
  • .log -- just adds the ".log" part back at the end

Remove the "echo" if you like the resulting commands.
If you want a static timestamp, then just use that text in place of the whole $(date ...) command substitution.

On your sample input, but with today's date, the output is:

mv -- foo1.log foo1_20210610.log
mv -- foo2.log foo2_20210610.log

Appending creation date on filename

You could use the following bash command:

find . -type f -exec bash -c 'mv "$1" "$(dirname "$1")/$(stat -c %w "$1" | sed "s/\([^.]*\).*/\1/;s/[-: ]/_/g")_$(basename "$1")"' _ {} \;

find looks for all regular file and rename using mv each file found.

The filename is built such that it gets the creation time appended at the beginning of the file.

In order to get the file creation time, I use stat with option -c %w instead of date -r that gives the modification time.

The sed command replaces the output from stat to the wanted format (with _).

How to append the timestamp of a process to the name of a file in Unix

You can do that with this bash script:

#!/bin/bash

TIMESTAMP=$(date +%s)

for f in /home/user/ingest/*
do
if [ -f "$f" ]; then
name=$(basename "$f")
mv $f /home/user/ingest/inbox/${name}_${TIMESTAMP}
fi
done

The ${TIMESTAMP} is the number of seconds since the epoch (Jan 1970). The for loop iterates through everything in the /home/user/ingest/ directory, and the if statement checks to see if the file is a regular file (not directory, not symlink), and then the file is moved to /home/user/ingest/inbox/ with the timestamp appended to the end.

Bash: Rename file name to unix timestamp of modification date

find . -type f -exec \
sh -c '
for i do
d=$(dirname "$i")
[ "$d" = / ] && d=
n=${i##*/}
echo mv "$i" "$d/u-$(stat -c %Y "$i") $n"
done' _ {} +
  • This operates recursively in the current directory (.). It only targets regular files (not directories etc). Modify -type f and other flags if needed.

  • It just prints the mv commands, so you can review them. Remove the echo to run for real.

  • We use find to list the target files, and its -exec flag to pass this list to a shell loop where we can parse and modify the filenames, including stat to get the modification time.

  • I don't know your use case, but a better solution may be to just save the output of: find . -type f -printf '%p u-%T@\n' in a file, for later reference (this prints the file path and modification time on the same line). Also, maybe a snapshot (if possible).

Command to assign timestamp to the name of a file

If you are using Bash (/bin/bash), this will put the name of the file into the variable file_name:

$ printf -v file_name 'db_%(%m%d%Y%H%M)T.sql' -2
$ echo "File name is: '$file_name'"
File name is: 'db_022420212146.sql'

You can do this at any time in your script since -2 is a special value representing the time Bash started, i.e. when your script was run.

If you are using a POSIX shell (/bin/sh), then you must add this at the beginning of your script:

file_name=$(date +db_%m%d%Y%H%M.sql)

(of course this would work with Bash too)

Linux Script to redirect output to log file with date filename

You can use date to choose the format of the log file. Assuming YYYY-MM-DD, you can use the following. Note using '>>' to append/create the log file.

java abc.java >> "logfile.$(date +'%Y-%m-%d').log"
# Test
echo abc.java >> "logfile.$(date +'%Y-%m-%d').log"

Also note that 'java abc.java' need to be reviewed. The java command is usually invoked with class name (java abc), and not the name of a file.



Related Topics



Leave a reply



Submit