dir1='/d/Dropbox/PhD/Experimental Design/APS/Processed_and_Graphed/InvariantQ'
echo $dir1
for f in A*.xlsx
do
str2=${f%?????}
if [[ ! -d $dir1/$str2 ]]; then
mkdir $dir1/$str2
else
echo "Directory" $dir1/$str2 "already exists, directory not created"
fi
if [[ ! -f $dir1/$str2/$f ]]; then
mv -v $f $dir1/$str2
else
echo "File" $dir1/$str2/$f "already exists, file not copied"
fi
done
I'm trying to get the following script to run, however when it attempts to mkdir $dir1/$str2, it creates:
/d/Dropbox/PhD/Experimental
and returns back the error:
create directory '/d/Dropbox/PhD/Experimental': file exists
create directory 'Design/APS/Processed_and_Graphed/InvariantQ': no such file or directory
I've tried coding the directory name with double quotations, or a '\' in front of the space in 'Experimental Design', but neither method seems to work... It seems this can be achieved in batch files using "usebackq" -is there a way to do this in GitBash for windows? If so, where in my code would it be applied?
Also, is anyone aware as to why testing a statement here using "[[" works, whereas a single "[" doesn't?
Quote your variables to prevent word splitting on the expansion.
dir1='/d/Dropbox/PhD/Experimental Design/APS/Processed_and_Graphed/InvariantQ'
echo "$dir1"
for f in A*.xlsx
do
str2=${f%?????}
if [[ ! -d $dir1/$str2 ]]; then
mkdir "$dir1/$str2"
else
echo "Directory $dir1/$str2 already exists, directory not created"
fi
if [[ ! -f $dir1/$str2/$f ]]; then
mv -v "$f" "$dir1/$str2"
else
echo "File $dir1/$str2/$f already exists, file not copied"
fi
done
It works with [[ because this is shell syntax, not an ordinary command. It recognizes variables specially and doesn't do work splitting on them. This is the same reason that it allows you to use operators like < without quoting them.
Related
I'm creating a bash script, but it does not seem to check if a folder exists, when it's based on variables. Although the folder does exists, when I cd into it.
#!/usr/bin/env bash
VAR1="/Users/nameuserhere/Desktop/";
VAR2=`date "+%Y-%m-%d"`;
VAR3="$VAR1$VAR2";
echo "folder path: $VAR3";
if [[ -f "$VAR3" ]]
then
echo "this/not does exists"
else
echo "this/not does not exist"
fi
Use -d, as -f check if it's a file:
-f FILE True if file exists and is a regular file
I have a shell script, which has a code block to find a file in the directory but it is not doing the job. I have a file in my directory "changeip.data", in one of the block i am tring to find the file, but it is not detecting the file. I want to check with the condition that the filename starts with "change".
cd /home/raymond
file = "changeip.data"
if [[ "$file" == change* ]]; then
echo "File found..."
else
echo "File not found..."
fi
Can somebody help me with this?
the problem in your code is extra space. make sure there is no space while pointing to file name. refer the following initilization:
file="changeip.data"
EDIT:
#==================
Full code:
#==================
file="changeip.data"
if [[ "$file" == change* ]]; then
echo "File found..."
else
echo "File not found..."
fi
The issue is that to check is a file exists, you need to use -e but this will only work with complete file names without globbing.
As an alternative, you could try the following:
if [[ "$(find -maxdepth 1 -name "zipp*pm2" | wc -l)" -gt "0" ]];
then
echo "File Found";
else
echo "File Not Found";
fi
This will count the output from the find command and if it is greater than 0, will return "File Found", otherwise "File Not Found"
On MacOS Catalina, I have a bash script with
if [[ ! -f $CR/home/files/Recovery_*.txt ]]
then
echo "File does not exists in /home/files directory. Exiting" >> $log
echo "Aborted - $CR/home/files/Recovery_*txt not exist"
exit
fi
Even though there are 2 files in the directory the script exits. If I list directory contents beforehand there are 2 files. If I change it as follows the if is skipped:
if [[ `ls -la $CR/home/files/Recovery_*.txt | wc -l` -eq 0 ]]
then
echo "No files are :"
exit
fi
I am wanting to use the if -f conditional.
Any suggestions please?
Cheers, C
If you use nullglob, a glob expression that doesn't match returns an empty string. This lets us count files in bash without spawning other processes. Create an array with the expression, then check its length.
shopt -s nullglob
files=($CR/home/files/Recovery_*.txt)
if [[ ${#files[#]} -eq 0 ]]
then
echo "No files"
exit
fi
[Edited]
The error was not the variables, but the missing shebang as the script has come across from W2K3 SFU.
The tip about shellchecker.net was awesome and I will use that from now.
Thanks.
I want to remove files with extension that was given by a user. My problem is that it print "Not Found" and "rm: cannot remove ‘*.txt’"
echo Extension?
read ext
if [ -e *$ext ]
then
rm *$ext
else
echo Not Found
fi
Try using the -z flag to check if the $ext variable is empty. The -e flag checks if a file exists.
#!/bin/bash
echo Extension?
read ext
if [ ! -z $ext ]
then
rm *.$ext
else
echo Not Found
fi
I also added a . to the rm command. This reflects the desire to remove by extension. Otherwise, you'd be removing any file that ended with the user input (i.e. program.c and a file named zodiac would both be deleted).
Use a bash array to ensure that white space is handled correctly.
#!/bin/bash
# ask for ext until user enters one
ext=''
while [[ -z $ext ]]; do
read -p 'Extension? ' ext
done
# find files
files=(*"$ext")
if [[ -e ${files[0]} )); then
# delete files (-- prevents injection)
rm -- "${files[#]}"
else
# no files to delete
echo "No files with extension: $ext"
fi
I have a shell (ksh) script. I want to determine whether a certain directory is present in /tmp, and if it is present then I have to delete it. My script is:
test
#!/usr/bin/ksh
# what should I write here?
if [[ -f /tmp/dir.lock ]]; then
echo "Removing Lock"
rm -rf /tmp/dir.lock
fi
How can I proceed? I'm not getting the wanted result: the directory is not removed when I execute the script and I'm not getting Removing Lock output on my screen.
I checked manually and the lock file is present in the location.
The lock file is created with set MUTEX_LOCK "/tmp/dir.lock" by a TCL program.
In addition to -f versus -d note that [[ ]] is not POSIX, while [ ] is. Any string or path you use more than once should be in a variable to avoid typing errors, especially when you use rm -rf which deletes with extreme prejudice. The most portable solution would be
DIR=/tmp/dir.lock
if [ -d "$DIR" ]; then
printf '%s\n' "Removing Lock ($DIR)"
rm -rf "$DIR"
fi
For directory check, you should use -d:
if [[ -d /tmp/dir.lock ]]; then
echo "Removing Lock"
rm -rf /tmp/dir.lock
fi