Bash: passing a variable to mv command option - bash

--Bash 4.1.17 (running with Cygwin)
Hello, I am trying to pass the date into the --suffix option on the move (mv) command. I am able to pass in a simple string (like my name) but unable to pass in the date. If you run the script below you will see that the mv command with the suffix="$var" works but suffix="$now" does not.
#!/bin/bash
dir="your directory goes here"
now="$(date "+%m/%d/%y")"
var="_CARL!!!"
echo "$now"
echo "$var"
cd "$dir"
touch test.txt
# error if already exists
mkdir ./stack_question
touch ./stack_question/test.txt
mv -b --suffix="$var" test.txt ./stack_question/
The idea is that if test.txt already exists when trying to move the file, the file will have a suffix appended to it. So if you run this script with:
--suffix="$var"
you will see that the stack_question directory contains two files:
test.txt & test.txt_CARL!!!
But, if you run this script with:
--suffix="$now"
you will see that in the stack_question directory only contains:
test.txt
Any help on this would be greatly appreciated!

It is because you have embedded / in your date format try
now="$(date +%m_%d_%y)"

Related

changing file names according to parent directory name

Hello I have several directories of this tendency:
cluster1_bin.101_res/
cluster1_bin.102_res/
cluster1_bin.103_res/
cluster1_bin.104_res/
in each of these direcories I have several files with ".gbk" suffix like the following ones:
cluster1_bin.101_res/k141_734976.region001.gbk
cluster1_bin.101_res/k141_753945.region001.gbk
cluster1_bin.101_res/k141_743978.region001.gbk
and I need to replace everything that is before .region001.gbk for it's parent directory name
this is the desired output:
cluster1_bin.101_res/cluster1_bin.101_res.region001.gbk
cluster1_bin.101_res/cluster1_bin.101_res.region001.gbk
cluster1_bin.101_res/cluster1_bin.101_res.region001.gbk
Is there a way I can do that?
Thanks for your time.
With a for loop and Parameter Expansion and mv to rename the files.
#!/usr/bin/env bash
for file in cluster1_bin.[0-9]*_res/*.gbk; do
path_name=${file%/*}
file_name=${file##*/}
region_with_extension=${file_name#*.}
echo mv -v "$file" "$path_name/$path_name.$region_with_extension" || exit
done
With your given input/data the output is:
mv -v cluster1_bin.101_res/k141_734976.region001.gbk cluster1_bin.101_res/cluster1_bin.101_res.region001.gbk
mv -v cluster1_bin.102_res/k141_753945.region001.gbk cluster1_bin.102_res/cluster1_bin.102_res.region001.gbk
mv -v cluster1_bin.103_res/k141_743978.region001.gbk cluster1_bin.103_res/cluster1_bin.103_res.region001.gbk
Remove the echo If you think the output is correct so mv can rename the files.

.sh file returned file path instead of file name

I am writing a .sh file to print the file names one by one. I have installed ubuntu in windows 10 and using the windows command prompt for executing below code. It is returning "E:/Official/Backups/GGG/*" instead of file names inside. I have also changed the EOL conversion to Unix(LF) by using notepad ++. please help.
#!/bin/bash
folder="E:/Official/Backups/GGG"
for entry in "$folder"/*
do
echo "$entry"
done
Running the script outputs:
$ bash test1.sh
E:/Official/Backups/GGG/*
Output of echo $-
himBHs
Output of ls -ld E:/Official/Backups/GGG
ls: cannot access 'E:/Official/Backups/GGG': No such file or directory
My bash in WSL does not recognize windows paths. If I want to access E:\Official\Backups\GGG I would have to use /mnt/e/Official/Backups/GGG.
I assume, the same goes for your WSL bash. Therefore the "path" E:/Official/Backups/GGG is just a non-existing directory and your observed behavior is to be expected. With bash's default settings a * just stays there as a literal if the directory does not exist or is empty. Example:
$ echo /dir/that/doesnt/exist/*
/dir/that/doesnt/exist/*
$ echo /dir/that/exists/but/is/empty/*
/dir/that/exists/but/is/empty/*
$ echo /dir/*
/dir/file1 /dir/file2 /dir/file3 ...
GGG folder is not exists. Please check and update with valid folder and try again.
#!/bin/bash
folder="E:"
for entry in "$folder"/*
do
echo "$entry"
done

Checkin if a Variable File is in another directory

I'm looking to check if a variable file is in another directory, and if it is, stop the script from running any farther. So far I have this:
#! /bin/bash
for file in /directory/of/variable/file/*.cp;
do
test -f /directory/to/be/checked/$file;
echo $?
done
I ran an echo of $file and see that it includes the full path, which would explain why my test doesn't see the file, but I am at a loss for how to move forward so that I can check.
Any help would be greatly appreciated!
Thanks
I think you want
#! /bin/bash
for file in /directory/of/variable/file/*.cp ; do
newFile="${file##*/}"
if test -f /directory/to/be/checked/"$newFile" ; then
echo "/directory/to/be/checked/$newFile already exists, updating ..."
else
echo "/directory/to/be/checked/$newFile not found, copying ..."
fi
cp -i "$file" /directory/to/be/checked/"$newFile"
done
Note that you can replace cp -i with mv -i and move the file, leaving no file left behind in /directory/of/variable/file/.
The -i option means interrogate (I think), meaning if the file is already there, it will ask you overwrite /directory/to/be/checked/"$newFile" (or similar) to which you must reply y. This will only happen if the file already exists in the new location.
IHTH
The command basename will give you just the file (or directory) without the rest of the path.
#! /bin/bash
for file in /directory/of/variable/file/*.cp;
do
test -f /directory/to/be/checked/$(basename $file);
echo $?
done

shell script to create folder daily with time-stamp and push time-stamp generated logs

I have a cron job which runs every 30 minutes to generate log files with time-stamp like this:
test20130215100531.log,
test20130215102031.log
I would like to create one folder daily with date time-stamp and push log files in to respective date folder when generated.
I need to achieve this on AIX server with bash.
Maybe you are looking for a script like this:
#!/bin/bash
shopt -s nullglob # This line is so that it does not complain when no logfiles are found
for filename in test*.log; do # Files considered are the ones starting with test and ending in .log
foldername=$(echo "$filename" | awk '{print (substr($0, 5, 8));}'); # The foldername is characters 5 to 13 from the filename (if they exist)
mkdir -p "$foldername" # -p so that we don't get "folder exists" warning
mv "$filename" "$foldername"
echo "$filename $foldername" ;
done
I only tested with your sample, so do a proper testing before using in a directory that contains important stuff.
Edit in response to comments:
Change your original script to this:
foldername=$(date +%Y%m%d)
mkdir -p /home/app/logs/"$foldername"
sh sample.sh > /home/app/logs/"$foldername"/test$(date +%Y%m%d%H%M%S).log
Or if the directory is created somewhere else, just do this:
sh sample.sh > /home/app/logs/$(date +%Y%m%d)/test$(date +%Y%m%d%H%M%S).log
You should use logrotate! It can do this for you already, and you can just write to the same log file.
Check their man pages for info:
http://linuxcommand.org/man_pages/logrotate8.html

Why aren't the BASH commands in for loop working

I have a simple code which is:
#!/bin/bash
#LaTex code generator for figures.
ls *.pdf > pdfs.file
ls *.ps > ps.file
pwd=$(pwd)
for i in {1..2}
do
# var=$(awk 'NR==$i' 'pdfs.file')
echo $pwd
echo $pwd > testfile
done
Why aren't the commands in the for loop working?
The $pwd isnt echoed neither is the testfile created.
I tried these commands without the for loop in a terminal and they work fine.
My bash file is made executable by chmod +x bashfile.sh
What I am trying to do is this:
Find pdfs or eps files and populate pdfs.file and eps.file with their file names.
Step through row by row and grab these file names and append to $pwd.
Then append $pwd$var to the include graphics command in latex.
I'm not sure what you're doing wrong, but this works fine for me:
for i in {1..2}; do
echo $PWD
echo $PWD > /tmp/testfile
done
echo "File contents: $(cat /tmp/testfile)"
This successfully returns the following:
/tmp
/tmp
File contents: /tmp
Did you write the bash file using a Windows editor? Maybe you have a problem with line terminators. Try dos2unix bashfile.sh.

Resources