start a shellscript with cygwin from a batch file that is in a different directory than C: - bash

I am trying to make my life easier and tried working with scripting.
Since the script I wanna use is a shellscript ( I couldn´t make it work in powershell had a problem in reading the xml file; so a colleague had coded a shell script that I am using now) I am trying to use it in a batch(cmd) file.
So here is the idea on how it should work:
we have a .sh script that is removing all the timestamps in the XML files in that directory that this .sh file is in.
Code:
#!/bin/bash
for i in `find . -name "*.xml"`
do
echo $i; sed -i '/UCOMPSTAMP/d' $i
done
for i in `find . -name "*.xml"`
do
echo $i; sed -i '/DAT name="UTIMESTAMP"/d' $i
done
for i in `find . -name "*.xml"`
do
echo $i; sed -i '/DAT name="U_INTF"/d' $i
done
for i in `find . -name "*.xml"`
do
echo $i; sed -i '/DAT name="U_SVCUSE"/d' $i
done
for i in `find . -name "*.xml"`
do
echo $i; sed -i '/DAT name="U_FSEQ"/d' $i
done
This script is working and deletes the timestamps in my xml file in this directory.
I have a directory U:\bla\bla\compare
I also export both xml files that I am going to compare in that directory.
Lets say XML_LIVE.xml and XML_TEST.xml
now I have a batch(called: "execute_sh.cmd") that tries to open the .sh file:
#echo off
C:\cygwin64\bin\bash -l /cygdrive/u/bla/compare/01_remove_timestamps.sh
pause
right now it doesnt do anything. Also doesn´t say that it can´t find the path. I tried using ./01_remove_timestamps.sh
U:\bla\Compare\01_remove_timestamps.sh
but I get the error that it couldn´t find the file then. If I try to execute the command in cygwin I have to change the directory with
cd /cygdrive/u/bla/compare/
and then
./remove_timestamps.sh
and this executes the shellscript so why is this not possible with the .cmd?
and my final .cmd (called: execute_all)
call %0\..\execute_sh.cmd"
has this code in so I just have to start this .cmd and everything is automatic.
This entire thing works if I put all these .cmd and .sh files and the xml files in my home directory in cygwin -> C:\cygwin64\home\myName
The code would be
#echo off
C:\cygwin64\bin\bash -l 01_remove_timestamps.sh
pause
But I wanna use the D: Drive and a specific directory there. I hope this is clear to understand my problem.

Related

Rename Two files in the Same Folder

Files
events-number1.10a.pdf
Result
events-number1.10a.docx.pdf
Ideal
events-number1.10a.pdf
events-number1.10a.docx.pdf
A simple rename command will do the job.
rename 's/(?=\.pdf$)/.docx/' *.pdf
You can try this simple bash script
#!/bin/bash
for file in *.pdf
do
new_file=$(echo "$file" | sed -r 's/(.*)(\.pdf)/\1.docx\2/')
mv $file $new_file
done
Output:
events-number1.index10a.docx.pdf
events-number1.index10b.docx.pdf
events-number1.index10c.docx.pdf
events-number2.index10a.docx.pdf
events-number2.index10b.docx.pdf
events-number2.index10c.docx.pdf
If you want copy the file using cp command instead of mv command
cp $file $new_file
So your existing files won't change.
Explanation :
Passing all the log file to for loop ,then split the file name to your expected result for using sed command and stored in one variable . Then mv the old file to new file that mean your expected file .

deleting files in a given subdirectory

I have a few subdirectories in a given folder, where a file d2.sh~ exists. I want to delete this file via following shell script, which, rather than writing in a .sh file I wrote on terminal, on one line. [Edit: been formatted properly here for clarity]
for i in `ls *`; do
if [ -d $i ]; then
cd $i
rm d2.sh~
cd ..
fi
done
This did not give me any errors but it failed to delete d2.sh~ from the subdirectories. So I want to know what mistake I have made above?
find /some/path -type f -name "d2.sh~" -delete
Your first mistake is trying to parse ls. See this link as to why.
Just use for i in *; do ....
If you need recursion then you need to look to find or if you have Bash 4.X you can do:
shopt -s globstar; for i in **/d2.sh~; do rm "$i"; done

Bash scripting, loop through files in folder fails

I'm looping through certain files (all files starting with MOVIE) in a folder with this bash script code:
for i in MY-FOLDER/MOVIE*
do
which works fine when there are files in the folder. But when there aren't any, it somehow goes on with one file which it thinks is named MY-FOLDER/MOVIE*.
How can I avoid it to enter the things after
do
if there aren't any files in the folder?
With the nullglob option.
$ shopt -s nullglob
$ for i in zzz* ; do echo "$i" ; done
$
for i in $(find MY-FOLDER/MOVIE -type f); do
echo $i
done
The find utility is one of the Swiss Army knives of linux. It starts at the directory you give it and finds all files in all subdirectories, according to the options you give it.
-type f will find only regular files (not directories).
As I wrote it, the command will find files in subdirectories as well; you can prevent that by adding -maxdepth 1
Edit, 8 years later (thanks for the comment, #tadman!)
You can avoid the loop altogether with
find . -type f -exec echo "{}" \;
This tells find to echo the name of each file by substituting its name for {}. The escaped semicolon is necessary to terminate the command that's passed to -exec.
for file in MY-FOLDER/MOVIE*
do
# Skip if not a file
test -f "$file" || continue
# Now you know it's a file.
...
done

Shell Script to update the contents of a folder - 2

I wrote this piece of code this morning.
The idea is, a text file (new.txt) has the details about the directory structure and the files in the directory.
Read new.txt, create the same directory structure at a destination directory (here it is /tmp), copy the source files to the corresponding destination directory.
Script
clear
DEST_DIR=/tmp
for file in 'cat new.txt'
do
mkdir -p $file
touch $file
echo 'ls -ltr $file'
cp -rf $file $DEST_DIR
find . -name $file -type f
cp $file $DEST_DIR
done
Contents of new.txt
Test/test1/test1.txt
Test/test2/test2.txt
Test/test3/test3.txt
Test/test4/test4.txt
The issue is, it executes the code, creates the directory structure, but instead of creating it at the end, it creates directories named test1.txt, test2.txt, etc. I have no idea why this is happening.
Another question: For Turbo C, C++, there is an option to check the execution flow? Is there something available in Unix, Perl and shell scripting to check the execution flow?
The script creates these directories because you tell it to on the line mkdir -p $file. You have to extract the directory path from you filename. The standard command for this is dirname:
dir=`dirname "$file"`
mkdir -p -- "$dir"
To check the execution flow is to add set -x at the top of your script. This will cause all lines that are executed to be printed to stderr with "+ " in front of it.
you might want to try something like rsync

basic shell script

I have some video files all ending in .wmv .mov .mpg. I have music files ending in .mp3 .wma. And finally I have some text files all end in the extension .txt
I wrote a shell script that generates subfolders, one for the music files, one for the video files, and one for the text files, and then organizes all of the files into the correct subfolders.
But I ran into a little problem ...
*** I would like the script to be interactive and to prompt the user if he/she wants to organize the files. Also, I would like the script to write a log file that contains, for each file, the original file name, as well as the new file path/name it was moved to. And I would like the script to accept a command line argument, which is the folder that contains the unorganized files. This should allow the script to be located and run from anywhere in the file system, and accept any folder of unorganized files.
Example:
organizefiles.sh mystuff/media
where the subfolders would go inside "media"
Any ideas on how to do that?
Thank you!
here's a partial implementation for you to start with. Try and do the rest yourself.
find /path -type f \( -iname "*.mp3" -o -iname "*.txt" \) -exec file -N "{}" + | while IFS=":" read -r filename type
do
case "$type" in
*[vV]ideo*|*AVI* ) echo "Video: $filename";;
*[Aa]udio*|*MPEG*ADTS*) echo "Audio file: $filename";;
*[Aa]scii*[tT]ext*) echo "Text: $filename" ;;
* ) echo "No type: $filename-> type: $type";;
esac
done
Please read bash tutorial or this to get familiarize with shell scripting.
I would recommend switching to python, much easier to write and maintain such a code.
As for bash:
Reading input: read
Reading command line arguments: see here
Writing to a log file, simply do echo "something" >> mylogfile.log
Here is the script I have so far
#!/bin/bash
mkdir movies
mkdir songs
mkdir textfiles
mv *.wmv movies
mv *.mov movies
mv *.mpg movies
mv *.mp3 songs
mv *.wma songs
mv *.txt text
ls -l movies, >> log.txt
ls -l songs >> log.txt
ls -l textfiles >> log.txt

Resources