I have a file structure like
folder/subfolder1/folders.txt,docker-compose.yml
folder/subfolder2/folders.txt,docker-compose.yml
These text files contain folders to be created in my $HOME, like appdata/subfolder1,subfolder2
I’m trying to create a script that does the following;
It should go over all the files in folder/* and watch for .txt files in subfolders. If there is no text file in subfolder1 I want it to echo “no txt file in subfolder1” but if there is a txt file in subfolder1 it should read it line by line and create the folders in my $HOME. It should also do the same for subfolder2 and so on.
It should do nothing with the .yml files in the directories.
I think it can be accomplished with something like
#!/bin/env bash
folder=“folder/*/*”
for f in $folder do
if [ $f = *.txt ] then xargs mkdir -p
else echo “no txt files in folder..”
fi
done
I think there could be a $(dirname $f) involved for echoing “no txt files in subfolder..”
I know I’m probably making a lot of mistakes but that’s why I came here, maybe some of you would like to help.
The reason for this script is I want to automate docker stack deploy for my docker swarm but unlike a regular docker-compose up swarm doesn’t create folders if they don’t exist.
Please just ask if I need to explain more about what it should and shouldn’t do.
EDIT:
I came up with some scripts but now I’m trying to combine the two,
cokehotdog#testvm:~$ for file in $files; do [[ $file == *.txt ]] && echo "$(basename $file) in $(basename $(dirname $file)) is a txt file" || echo "$(basename $file) in $(basename $(dirname $file)) is not a txt file"; done
test.txt in app1 is a txt file
test1.yml in app1 is not a txt file
test2.txt in app2 is a txt file
test2.yml in app2 is not a txt file
This should be combined with this
cokehotdog#testvm:~$ for file in $files; do [[ $file == *.txt ]] && cat $file | xargs mkdir -p -- && while read -r line; do echo "$line created";done < $file ; done
/home/cokehotdog/appdata/app1 created
/home/cokehotdog/appdata/app2 created
But when I try something like this I get an error and I’m stuck now
cokehotdog#testvm:~$ for file in $files; do [[ $file == *.txt ]] && cat $file | xargs mkdir -p -- && while read -r line; do echo "$line created";done < $file || echo "$(basename $file) in $(basename $(dirname $file)) is not a txt file"; done
cat: 'test/*/*.txt': No such file or directory
mkdir: missing operand
Try 'mkdir --help' for more information.
Try:
find folder -type f -name 'folders.txt' |
while IFS= read -r l; do
(
cd "$(dirname "$l")"
xargs -d '\n' -t echo mkdir -p < "$l"
)
done
Related
I came across scenario using shell script. I need to delete the folder and Zip if it has the same name. Can any one please help me in this .
Example
Below is the directory path in which script need to search the same name in the directory (here it needs to print and delete example and example.zip)
Path:/tmp/test/
/tmp/test/example
/tmp/test/example.zip
/tmp/test/zack
You can use script as below:
#!/bin/bash
parent_dir=/tmp/test/
for i in `ls /tmp`
do
if [[ $i != *.zip ]]; then
if [[ -f /tmp/$i.zip ]]; then
array=$array" "$i
fi
fi
done
array=( $array )
for i in ${array[#]}
do
rm -r $parent_dir$i
rm -r $parent_dir$i".zip"
done
This should do a trick, even suitable for a cronjob:
find $DIR_PATH -type d -exec sh -c '[ -f "{}.zip" ] && rm -fr {}.zip {}' \;
Just set DIR_PATH to where youre searching
I'm working on a bash script that should do the following: for every directory beginning with Event_*, (in cat eventList), cd into the directory, and if the string "ZJ.ROT" exists in the file *.mcp, I want to copy the file "ROT" to another directory. In simpler terms: loop through directories: if string "ZJ.ROT" exists in a file in that directory, output another file from that directory to a separate directory.
#!/bin/bash
mkdir newdire
for dir in `cat eventList`; do
cd $dir
pwd
if grep "ZJ.KNYN" *.mcp; then
cp "ROT" "newdire"
fi
done
The error I get is:
./azim.sh: line 5: cd: Event_2014.11.21.10.10.19.630: No such file or directory
/Users/files/Event_2013.12.01.06.29.57.800
grep: *.mcp: No such file or directory
For some reason, this for loop isn't looping through each directory, but it's stuck in the first directory Event_2013.... Any ideas about how to implement this code?
After the first time you cd to a subdirectory you are in it for all future loop iterations so your subsequent cds will fail, as you are experiencing. You also need to quote your variables and there's other issues. Try this:
pwd="$PWD"
mkdir newdire
while IFS= read -r dir; do
cd "$dir"
grep -Fq "ZJ.KNYN" *.mcp &&
cp "ROT" "${pwd}/newdire"
cd "$pwd"
done < eventList
but of course you don't actually need to cd:
mkdir newdire
while IFS= read -r dir; do
grep -Fq "ZJ.KNYN" "$dir"/*.mcp &&
cp "${dir}/ROT" newdire
done < eventList
Problem seems to be here:
if grep "ZJ.KNYN" *.mcp; then
You should use -q option in grep to suppress the output and check the return status like this:
if grep -qF "ZJ.KNYN" *.mcp; then
-F is for fixed string search.
Also there is no need to change directory inside the loop.
Your full script can be better rewritten as:
#!/bin/bash
mkdir newdire
for dir in Event_*; do
if [[ -d "$dir" ]] && grep -qF "ZJ.KNYN" "$dir"/*.mcp 2>/dev/null; then
cp "$dir/ROT" "newdire/"
fi
done
I am new to Unix shell scripting. I have a small task of moving files into another directory based on their names.
I have a directory named Cars containing .csv files. I have to read the .csv file names, and move each file into another directory based on the filename, as follows:
BMW_c.csv must go into the BMW/c/ directory.
Mercedes_x.csv must go into the Mercedes/x/ directory.
I tried using for and if loop but couldn`t do it till sub directory.
I highly appreciate your help.
Something like this might work
for f in *.csv; do
DIR="$( echo ${f%.*} | tr '_' '/')"
mkdir -p "./$DIR"
mv "$f" "$DIR"
done
It will read all *.csv files, replace '_' by '/' in the file names (with .csv removed), create the directory and move the file. There will be errors if there are no csv files in the current directory.
I have done this and tried,it works.If any modifications or enhancements in the script you can post your answers..
cd /DIR/Cars/BMW
for f in *.csv
do
filename="${f##*/}"
echo ${filename}
if [[ "${f}" == *c* ]]
then
echo "moving files..."
mv "${f}" /BMW/c/
fi
done
cd /DIR/Cars/Mercedes
for f in *.csv
do
filename="${f##*/}"
echo ${filename}
if [[ "${f}" == *x* ]]
then
echo "moving files..."
mv "${f}" /Mercedes/x/
fi
done
i'm currently working through an exercise book and I have to create a shell script that will find a file from any directory and move it.
Though I am having difficulties as the file could be in any directory (so I do not have a path to find it). I have used the find option with the -print flag tho what would be the next step to move it using mv command?
My code so far reads in a variable, detects if a file has been entered, if it is a file or a directory, or if it exists.
The next stage as mentioned above is to find the file and then move it into a "test" file.
If anyone has any recommendations it would be greatly appreciated.
#!/bin/bash
bin="deleted"
if [ ! -e bin ] ; then
mkdir $bin
fi
file=$1
#error to display that no file has been entered
if [[ ! $file ]]; then
echo "no file has been entered"
fi
#file does not exist, display error message
if [[ ! -f $file ]]; then
echo "$file does not exsist!"
fi
#check to see if the input is a directory
if [[ -d $file ]]; then
echo "$file is a directory!"
if [[ -e $file ]]; then *** move to test folder
****This is where I am having the problems
find / -type f -name FILENAME | xargs -I foobar echo mv foobar /tmp (remove echo to make the command actually work .. i put it there just to save yourself from accidentally moving files just to try out the command)
Note that -I foobar means that in mv foobar /tmp replace the foobar string with full path of the file found.
for example, try: find / -type f -name FILENAME | xargs -I foobar foobar is a cool file
I havent been able to find an answer that best suites my needs, and I appologize if someone is able to find it easily.
I have a script that works to move files into folders based on their names. It worked perfectly until I realized that The files where missing their extension once I fixed this (another script was responsible for the file naming based on an email subject line) Once I fixed this problem It then started making a folder for each file. Is there anyway I can make this script drop everything in the folder name before the first (.)
Here is the script
#!/bin/bash
#folder script
#Benjamin D. Schran
MAIN_DIR=/PGHWH1/Photos
cd $MAIN_DIR
find . -maxdepth 1 -type f > SCRIPT_LOG1
find . -name '* *' | while read fname
do
new_fname=`echo $fname | tr " " "_"`
if [ -e $new_fname ]
then
echo "File $new_fname already exists. Not replacing $fname"
else
echo "Creating new file $new_fname to replace $fname"
mv "$fname" $new_fname
fi
done
find . -maxdepth 1 -type f | while read file;
do
f=$(basename "$file")
f1=${f%.*}
if [ -d "$f1" ];
then
mv "$f" "$f1"
else
mkdir "$f1"
chmod 777 "$f1"
mv "$f" "$f1"
fi
done
SCRIPTLOG=Script_log.$(date +%Y-%m-%d-%H-%M)
find . -type f > SCRIPT_LOG2
cd /PGHWH1/bin
sh scriptlog.sh > $SCRIPTLOG.html
mv $SCRIPTLOG.html /PGHWH1/log
rm $MAIN_DIR/SCRIPT_LOG1 $MAIN_DIR/SCRIPT_LOG2
What I need it to do is to take a files that is
Filename-date.%.jpg
and make
Foldername-date
then move the files of
Filename-date.1.jpg
Filename-date.2.jpg
Filename-date.3.jpg
to the appropriate folder
Foldername-date
but the current output is
Foldername-date.1
Foldername-date.2
Foldername-date.3
Any help at all would be appreciated
The following lines do the job in my bash:
#first create a tmp file with unique directory names
ls *.jpg | awk -F'.' '{print $1}' | uniq > dirs
#second create the directories
mkdir -p `cat dirs`
#third move the files
for i in `cat dirs`; do mv $i*.jpg $i/; done
#(optionally) remove the tmp file
rm dirs