Is there a way I can take user input and make it into a file? - bash

I am not able to find a way to make bash create a file with the same name as the file the user dragged into the terminal.
read -p 'file: ' file
if [ "$file" -eq "" ]; then
cd desktop
mkdir
fi
I am trying to make this part of the script take the name of the file they dragged in so for example /Users/admin/Desktop/test.app cd into it copy the "contents" file make another folder with the same name so test.app for this example and then paste the contents file into that folder and delete the old file.

From your .app example, I assume you are using MacOS. Therefore you will need to test this script yourself since I don't have MacOS, but I think it should be doing what you want. Execute it as bash script.sh and it will give you your desired directory test.app/contents in the current working directory.
#! /bin/bash
read -rp 'file: ' file
if [ -e "$file" ]; then
if [ -e "$file"/contents ]; then
base=$(basename "$file")
mkdir "$base"
cp -R "$file"/contents "$base"
rm -rf "$file"
else
echo "The specified file $file has no directory 'contents'."
fi
else
echo "The specified file $file does not exist."
fi

Related

Create new Directories with Bash Script

I'd like to create a script to run every hour (with crontab) to make a folder with the name of any file with the correct extension (minus the extension) and move that file into it. So the end result would be the script would execute, find every .mp4 file in /Directory, create a folder for each of them with the same name as the file (minus extension) in /Other/Directory, and move the file into the matching folder. I can understand not wanting to write something for someone for free, but if you could point me in the right direction, I would really appreciate it.
EDIT: Thanks to #Barmar for the help!
#!/bin/bash
cd "/home/kali/Videos"
for FILE in *;do
bn=$(basename $FILE .mp4)
mkdir /home/kali/Videos/$bn;done
mv $bn.mp4 /home/kali/Videos/$bn
The script you would be looking for is as follows:
#!/bin/bash
REPOSITORY="/home/kali/Videos"
cd "${REPOSITORY}"
### This approach is best for handling filenames that might have spaces or scpecial characters.
ls |
while [ true ]
do
read FILE
if [ -z "${FILE}" ] ; then break ; fi
if [ -f "${FILE}" ]
then
bn=`basename "${FILE}" ".mp4" `
mkdir "${REPOSITORY}/$bn"
mv "${FILE}" "${REPOSITORY}/$bn"
( cd "${REPOSITORY}/$bn" ; extract_images "./${FILE}" )
fi
done

How to pass arguments to a file which the locations to switch in the shell script

I have a shell script which takes an location input from a text file. I had loop in the script to read line(location) and change directory to the location and list the files.
In the below the location directory "switch" changes because this location may not exists on the all the servers. I have to pass this directory as an argument to the file and pass this location to the script.
locations.txt has below content.
/usr/test/home/process_file/switch/process.txt
shell script:
for i in `cat locations`;
do
echo $line
cd $i
if [ -d "$i" ]
then
cd $i
pwd
ls -ltr
else
exit
fi
done
Storing a filename in a file seems a little inefficient.
Don't read lines with for
cd will return non-zero if the directory does not exist.
while IFS= read -r dir; do
if cd "$dir" 2>/dev/null; then
pwd
ls -ltr
else
echo "no such directory: $dir"
fi
done < /usr/test/home/process_file/switch/process.txt

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

Zip I/O error: No such file or directory in bash script

I've been writing some code to (mostly) automate password protecting and compressing/archiving folders and files. However, the code seems to hate me.
I've run it line by line, and it always chokes on the zip command, even when the $file and $source are correct and valid.
Any ideas?
Here's the source code:
#!/bin/bash
echo "Drag in the source file"
read source
echo
echo "Drag in the destination file, or press enter to select the Desktop"
read destination
echo
if [ -z "$destination" ]
then destination="$PWD/Desktop"
echo "Destination is set to the desktop"
fi
echo "Type the name of the file to make"
read file
if [ -z "$file" ]
then file="archive"
echo "File name set to archive.zip"
fi
file="${destination}/${file}"
if [ -d $"source" ]
then zip -erj "$file" "$destination"
else zip -ej "$file" "$destination"
fi
There are a couple of problems in your code:
if [ -z "$destination" ]
then destination="$PWD/Desktop"
echo "Destination is set to the desktop"
fi
$PWD is the current working directory. It is your home directory when you open a Terminal but it changes everytime you run cd.
The Desktop directory is $HOME/Desktop.
If you don't run the script from your home directory, most probably $PWD/Desktop doesn't exist and this is a cause for errors; zip doesn't attempt to create the destination directory for the archive you ask it to build. If the directory doesn't already exist it displays an error message and exits.
Another problem is on the invocation of zip:
if [ -d $"source" ]
then zip -erj "$file" "$destination"
else zip -ej "$file" "$destination"
fi
You probably want to archive the file $source or the files in the $source directory (if it is a directory) but you mistakenly put $destination as the file/directory to archive in the zip command line.
if [ -d $"source" ] -- it should be "$source", otherwise the quote are useless and if $source contains spaces the script will exit with a syntax error.
One last thing: zip doesn't mind receiving -r in the command line when it is asked to archive only one file. You can replace the entire if/else block above with a single command:
zip -erj "$file" "$source"

Recursively copying a file into multiple directories, if a directory does not exist in Bash

so I need to copy the file /home/servers/template/craftbukkit.jar into every folder inside of /home/servers, Ex. /home/servers/server1, /home/servers/server2, etc.
But I only want to do it if /home/servers/whateverserveritiscurrentlyon/mods does not exsist. This is what I came up with and was wondering if it will work:
echo " Script to copy a file to all server directories, only if mods does not exist in that directory"
for i in /home/servers/*/; do
if [ ! -d "$i/mods" ]; then
cp -f /home/servers/template/craftbukkit.jar "$i"
fi
done
echo " completed script ..."
Looks like it should work. To non-destructively test, change the cp -f ... line to say echo cp -f ... and review the output.
It could also be somewhat shortened, but it wouldn't affect efficiency much:
for i in /home/servers/*/
do
[[ -d "${i}/mods" ]] || cp -f /home/servers/template/craftbukkit.jar "${i}/."
done

Resources