How to change drive in Makefile? - bash

The target (rule) in my Makefile has a series of commands. First few commands should be executed from D:\ drive. After this, I should change my directory to C:\ so that I can execute a file in C:\ drive. But, I am not able to change drive. I tried the following ways:
C: (it works in cmd but not in Makefile)
cd /d C: (not working)
cd C: (not working)
Please let me know how to change drive from within a make rule.

This can be achieved by using either ; or && \
cd d:\folder1 && \
dir && \
echo "all files in d:\folder1 are listed"
cd c:\folder2 && \
dir && \
echo "all files in c:\folder2 are listed"
is equivalent to
cd d:\folder1; dir; echo "all files in d:\folder1 are listed"
cd c:\folder2; dir; echo "all files in c:\folder2 are listed"

Related

BASH Script for creating multiple directories, moving files, and then renaming said files

I am trying to make a bash script to create directories with the same name as each file in a given directory, then move said files to their respective directories, and then rename the files.
Basically - a quantum chemistry program that I use requires that the input files be named "ZMAT". So, if I have multiple jobs, I currently need to manually create directories, and then move the ZMAT files into them (can only run one job per folder).
When I run my code, I get "binary operator expected". I am not sure what this means. Some help please.
Here is what I have so far:
#!/bin/bash
if [ -e *.ZMAT ];
then
echo "CFOUR Job Detected"
for INPFILE in *.ZMAT; do
BASENAME=$(basename $INPFILE )
INPFILE=$BASENAME.ZMAT
OUTFILE=$BASENAME.out
XYZFILE=$BASENAME.xyz
ERRORFILE=$BASENAME.slu
if [ ! -e $ERRORFILE ];
then
# Create folder in scratch directory with the basename
mkdir /scratch/CFOUR/$BASENAME
# Move the file to its directory
mv -f $INPFILE /scratch/CFOUR/$BASENAME
# cd to the new directory
cd /scratch/CFOUR/$BASENAME
# Change the file name to just ZMAT
mv -f $INPFILE ZMAT
echo "Submitting CFOUR Job"
# Submit to scheduler
#RUN_COMMAND="sbatch -J $BASENAME _CFOUR_MRCC_SLURM.SUB"
#eval $RUN_COMMAND
else
echo "Error File Detected - Not Submitting Job"
fi
done
fi
An alternative would be to create symlinks to the original files.
As you said before, each ZMAT symlink would need to be in its own directory.
The upside is that the original data doesn't move, so less risk of breaking it, but the tool you want to use should read the symlinks as if they are the files it is looking for.
This one-liner creates an out directory in the current folder that you could subsequently move wherever you want it. You could easily create it where you do want it by replacing "out" with whatever absolute path you wanted
for i in *.ZMAT; do mkdir -p out/$i ; ln -s $PWD/$i out/$i/ZMAT ; done
I believe I have solved my problem. Here is the new script, which appears to be working fine. Any input is welcome though!
#!/bin/bash
SUBDIR=$(pwd)
for i in *.ZMAT; do
BASENAME=$(basename $i .ZMAT)
INPFILE=$BASENAME.ZMAT
OUTFILE=$BASENAME.out
XYZFILE=$BASENAME.xyz
ERRORFILE=$BASENAME.slu
if [ ! -e $ERRORFILE ];
then
mkdir /scratch/CFOUR/$BASENAME # Create Scratch Folder
cp $INPFILE /scratch/cdc/CFOUR/$BASENAME # Move Input to Scratch
cd /scratch/CFOUR/$BASENAME #cd to Scratch Folder
mv -f $INPFILE ZMAT # Change Input Name
echo "Submitting CFOUR Job"
# Submit to scheduler
#RUN_COMMAND="sbatch -J $BASENAME _CFOUR_MRCC_SLURM.SUB"
#eval $RUN_COMMAND
cd $SUBDIR #Go back to SUBDIR
else
echo "Error File Already Exists"
fi
done

how to unzip a file using unzip command?

I have an script which creates a folder named "data". Then it downloads a file using wget and these files (.zip format) are moved from the current directory to the folder "data". After that what I want is to unzip these files. I'm using unzip filename.zip and it works when I use it on the cmd, however I don't know why it's not working in the script.
Here is the script:
#!/bin/bash
mkdir data
wget http://187.191.75.115/gobmx/salud/datos_abiertos/datos_abiertos_covid19.zip && mv datos_abiertos_covid19.zip data && unzip datos_abiertos_covid19.zip
wget http://187.191.75.115/gobmx/salud/datos_abiertos/diccionario_datos_covid19.zip && mv diccionario_datos_covid19.zip data && unzip diccionario_datos_covid19.zip
datos_abiertos_covid19.zip and diccionario_datos_covid19.zip are the files I want to unzip once they are in my folder "data". I would really appreciate if someone can help me. Thanks in advance!
It fails because unzip foo.zip assumes foo.zip is in the current directory, but you just moved it to a subdirectory data. Interactively, you probably cd data first and that's why it works.
To make it work in your script, just have your script cd data as well:
#!/bin/bash
mkdir data
cd data || exit 1
wget http://187.191.75.115/gobmx/salud/datos_abiertos/datos_abiertos_covid19.zip && unzip datos_abiertos_covid19.zip
That way, the file is downloaded directly to the data directory so no mv is necessary, and the unzip command works as expected.
My approach:
#!/bin/bash
set -e # Exit if any command fails
mkdir data
pushd ./data >/dev/null
for i in 'datos_abiertos_covid19.zip' 'diccionario_datos_covid19.zip'; do
# Don't unzip (or exit) if 'wget' fails, don't exit if 'unzip' fails
wget "http://187.191.75.115/gobmx/salud/datos_abiertos/$i" -O "./$i" || continue
unzip "./$i" || true
done
popd >/dev/null
The file names don't need to be quoted in this case, but I did so anyway, to emphasise you can/should do so if necessary
You could of course use variables for the file list, URL, download dir, etc. if you wanted to build a more general script for downloading zip files
I know it's marked bash, but worth mentioning: pushd and popd are not defined in POSIX, you can change those to cd ./data and cd .. for more portability. Obviously wget is not POSIX either, but very common (see this thread for interesting info on that topic)

Fix the Bat File to make it work in Windows

I'm not familiar with working on Windows command prompt. I've to fix this batch file to make it work in Windows. I understand that this isn't a doubt. But this is stopping my progress and any help would be appreciated.
ndk-build clean &&
ndk-build APP_PLATFORM=android-15 NDK_LIBS_OUT=./sdk_core_bin NDK_OUT=./sdk_core_obj &&
echo "moving .so files to /src/main/libs" &&
cp -R ./sdk_core_bin/. ./src/main/libs &&
rm -r ./sdk_core_bin &&
rm -r ./sdk_core_obj
This is not a batch file. You probably want to convert a bash shell script to a batch file. There are multiple problems with this:
You can't have && at the end of the line because Windows commands can only be in one line unless you escape the new line with ^
Windows path is separated by backslash \ instead of slash. And it searches in the current folder first so you don't have to use . at the beginning of the path
echo is an internal command that doesn't accept parameters so you can't use quotes with it
The result might be like this
ndk-build clean && ^
ndk-build APP_PLATFORM=android-15 NDK_LIBS_OUT=sdk_core_bin NDK_OUT=sdk_core_obj && ^
(echo moving .so files to src\main\libs) && ^
copy sdk_core_bin src\main\libs && ^
rd /s sdk_core_bin && ^
rd /s sdk_core_obj

How do I save the directory from popd to a variable without changing the directory?

I know I've run into this problem on my Linux box, but right now I'm on Mac OS X and I need to do the same thing. I want to use pushd and popd to call scripts or binaries in several locations, but I need to keep the same working directory during this time.
This is a test script. I think this is the dumb way I did this beforehand:
cd ~
pushd . 1>/dev/null
cd Documents
NEW_DIR=`pwd`
OLD_DIR=$(`popd`)
cd $OLD_DIR
echo Current directory: `pwd`
echo New directory: $NEW_DIR
Which results in:
$ ./pushpop.sh
./pushpop.sh: line 5: cd: ~: No such file or directory
Current directory: /Users/NobleUplift
New directory: /Users/NobleUplift/Documents
It works, but not without an error.
popd is a command which will pop the top of the directory stack and change your working directory to it, so you don't need to use cd. Hence your pushpop.sh should read like:
#!/bin/bash
cd ~/
pushd . 1>/dev/null
cd Documents
NEW_DIR=`pwd`
popd
echo Current directory: `pwd`
echo New directory: $NEW_DIR
And you'll get output as you desire:
~
Current directory: /home/imp25
New directory: /home/imp25/Documents
Edit following OPs comments
If you want to capture the output of popd without moving directory, it's probably best to interograte the directory stack which pushd adds to and popd pops off. You can view the stack with the command dirs, which will give a list of directories, the first being your current working directory, i.e.:
cd ~
pushd .
cd Documents
pushd .
dirs
~/Documents ~/Documents ~
You can access specific entries in the stack with the +N and -N options to dirs (+N starts counting from the left, -N starts counting from the right). If you want to get the last thing you pushed to the stack it can be accessed with dirs +1.
Modifying your script would give you something like:
cd ~/
pushd . 1>/dev/null
cd Documents
NEW_DIR=`pwd`
OLD_DIR=$(dirs -l +1)
cd $OLD_DIR
echo Current directory: `pwd`
echo New directory: $NEW_DIR
Here $(dirs -l +1) gets the top of the stack you pushed and returns it in long form (expanding ~ to /home/foo for example). I think the error you're getting is around cd not handling ~ as a directory properly, hence the use of the -l option.

OSX Bash Script working with Files/Folders with spaces in the name

I'm trying to build a BASH script on OS X (10.6/10.7) to process a folder called QCExports which has folders with people's names in it in the format "LAST, First", i.e. "BOND, James".
When I run the following script, everything works but it falls over on folder or filenames with a space in them.
Script Code:
#!/bin/bash
echo "QuickCeph Export Script"
#Set Path to Process & Paths to Copy To
pathToQCExports=/Users/myuser/Desktop/QCExports
sureSmilePath=/Users/myuser/Desktop/QCExportsForSureSmile
sesamePath=/Users/myuser/Desktop/QCExportsForSesame
blankReplace=""
#Process Each Name
find $pathToQCExports -type d | while read name ; do
#escaping the folder with a space in the name
nameParsed=${name/", "/",\ "}
echo "Processing: "$nameParsed
pathSureSmile=${nameParsed/$pathToQCExports/$sureSmilePath}
pathSesame=${nameParsed/$pathToQCExports/$sesamePath}
mkdir $pathSesame
mkdir $pathSureSmile
echo "Folders Created"
#Copy For SureSmile
echo ${pathSureSmile}"/Suresmile-Frontal\ Photo.jpg" ${pathSureSmile}"/Suresmile-Frontal\ Photo.jpg"
#cp `${$pathSureSmile}"/Suresmile-Frontal\ Photo.jpg" ${pathSureSmile}"/Suresmile-Frontal\ Photo.jpg"`
#Copy For Sesame
echo ${pathSesame}"/Suresmile-Frontal\ Photo.jpg" ${pathSesame}"/S02.jpg"
#cp `${pathSesame}"/Suresmile-Frontal\ Photo.jpg" ${pathSesame}"/S02.jpg"`
done
echo "Completed";
Output:
QuickCeph Export Script
Processing: /Users/myuser/Desktop/QCExports/BOND,\ James
mkdir /Users/myuser/Desktop/QCExportsForSesame/BOND,\ James
mkdir: James: File exists
mkdir /Users/myuser/Desktop/QCExportsForSureSmile/BOND,\ James
mkdir: James: File exists
Folders Created
/Users/myuser/Desktop/QCExportsForSureSmile/BOND,\ James/Suresmile-Frontal\ Photo.jpg /Users/myuser/Desktop/QCExportsForSureSmile/BOND,\ James/Suresmile-Frontal\ Photo.jpg
/Users/myuser/Desktop/QCExportsForSesame/BOND,\ James/Suresmile-Frontal\ Photo.jpg /Users/myuser/Desktop/QCExportsForSesame/BOND,\ James/S02.jpg
Completed
On OS X usually in the terminal, you use a \ to escape a space in a folder or filename, but that doesn't seem to work.
I notice that it's interpreting the spaces as a normal space would be interpreted on the command line and thinking I want to execute the command on two files - i.e. it's not passing the \ onwards. I end up with a folder called "Bond,\" and a folder called "James" in the folder I execute the script from.
Note, I deliberately have the cp commands # out at the moment, so they aren't being executed... the problem is the same for both creating the folders & copying the filenames.
If I copy and paste the "echo'd" version of these commands into a terminal window, the commands work! But when BASH executes them, it doesn't respect the . :(
Any ideas?
Thanks!!
John
See my modifications on your script, you don't have to substitute spaces like you tried.
Moreover, you must choose if you backslash the spaces or if you are using quotes.
The simple way is to use double quotes.
Good doc about quotes, see http://mywiki.wooledge.org/Quotes and http://wiki.bash-hackers.org/syntax/words
#!/bin/bash
echo "QuickCeph Export Script"
#Set Path to Process & Paths to Copy To
pathToQCExports=/Users/myuser/Desktop/QCExports
sureSmilePath=/Users/myuser/Desktop/QCExportsForSureSmile
sesamePath=/Users/myuser/Desktop/QCExportsForSesame
blankReplace=""
#Process Each Name
find $pathToQCExports -type d | while read nameParsed ; do
echo "Processing: $nameParsed"
pathSureSmile="${nameParsed/$pathToQCExports/$sureSmilePath}"
pathSesame="${nameParsed/$pathToQCExports/$sesamePath}"
mkdir "$pathSesame"
mkdir "$pathSureSmile"
echo "Folders Created"
#Copy For SureSmile
echo "${pathSureSmile}/Suresmile-Frontal Photo.jpg" "${pathSureSmile}/Suresmile-Frontal Photo.jpg"
#Copy For Sesame
echo "${pathSesame}/Suresmile-Frontal Photo.jpg" "${pathSesame}/S02.jpg"
done
echo "Completed"

Resources