output to a file in script directory - linux

This probably quite basic but I have spent whole day finding an answer without much success.
I have an executable script that resides in ~/Desktop/shell/myScript.sh
I want a single line command to run this script from my terminal that outputs to a new directory in same directory where the script is located no matter what my present working directory is.
I was using:
mkdir -p tmp &&
./Desktop/shell/myScript.sh|grep '18x18'|cut -d":" -f1 > tmp/myList.txt
But it creates new directory in present working directory and not on the target location.
Any help would be appreciated.
Thanks!

You could solve it in one line if you pre-define a variable:
export LOC=$HOME/Desktop/shell
Then you can say
mkdir -p $LOC/tmp && $LOC/myScript.sh | grep '18x18' | cut -d":" -f1 > $LOC/tmp/myList.txt
But if you're doing this repeatedly it might be better long-term to wrap myScript.sh so that it creates the directory, and redirects the output, for you. The grep and cut parameters, as well as the output file name, would be passed as command-line arguments and options to the wrapper.

How about this:
SCRIPTDIR="./Desktop/shell/" ; mkdir "$SCRIPTDIR/tmp" ; "$SCRIPTDIR/myScript.sh" | grep '18x18' | cut -d ":" -f 1 > "$SCRIPTDIR/tmp/myList.txt"
In your case you have to give the path to the script anyway. If you put the script in the path where it is automatically searched, e.g. $HOME/bin, and you can just type myScript.sh without the directory prefix, you can use SCRIPTDIR=$( dirname $( which myScript.sh ) ).
Mixing directories with binaries and data files is usually a bad idea. For temporary files /tmp is the place to go. Consider that your script might become famous and get installed by the administrator in /usr/bin and run by several people at the same time. For this reason, try to think mktemp.

YOUR SCRIPT CAN DO THIS FOR YOU WITH SOME CODES
Instead of doing this manually from the command line and who knows where you will move your script and put it. add the following codes
[1] Find your script directory location using dirname
script_directory=`dirname $0`
The above code will find your script directory and save it in a variable.
[2] Create your "tmp" folder in your script directory
mkdir "$script_directory/tmp 2> /dev/null"
The above code will make a directory called "tmp" in your script directory. If the directory exist, mkdir will not overwrite any existing directory using this command line and gave an error. I hide all errors by "2> /dev/null"
[3] Open your script and modify it using "cut" and then redirect the output to a new file
cat "$0"|grep '18x18'|cut -d":" -f1 > "$script_directory"/tmp/myList.txt

Related

how to copy file to multiple sub directories linux

I have a file needs to copy unique directory call test
directory structure as below
/contentroot/path/a/x/test
/contentroot/path/a/y/test
/contentroot/path/a/z/test
--------------------------
as above I have more then 250 combination test directory
I have try below command ( by using asterisk) but it's only copy one test directly only and giving issue (cp: omitting directory )
cp myfile.txt /contentroot/path/a/*/test
any Help
Perhaps a for loop?
for FOLDER in /contentroot/path/a/*/test; do
cp myfile.txt $FOLDER
done
You can feed the output of an echo as an input to xargs. xargs will then run the cp command three times, appending the next directory path piped to it from the echo.
The -n 1 option on the xargs command is so it only appends one of those arguments at a time to the cp each time it runs.
echo /contentroot/path/a/x/test /contentroot/path/a/y/test /contentroot/path/a/z/test | xargs -n 1 cp myfile.txt
Warnings! Firstly this will over-write files (if they exist) and secondlt any bash command should be tested and used at the runners risk! ;)

Bash Script for Moving Variable string (files) with wildcard

I would like to ask some help regarding my script below:
#!/bin/bash
year=$(date +%Y)
lastyear=$((year-1))
month=$(date +%m)
log="$lastyear$month"
mkdir -p "/root/temp/$lastyear"
mkdir -p "/root/temp/$lastyear/$month"
cd /root
mv -f "*$log*" "/root/temp/$lastyear/$month"
Error Prompt is
mv: cannot stat `*201602*': No such file or directory
My target was to move all the files that has the specific "201602" string in file name to a specific location.
Sample logs files is OUTXXX-201602XXX, INXXX-201602XXX, 201602XXXX.
This will be implemented through crontab, because there are about 500k+ log files to be transferred and using find will receive a too much argument error T_T.
Any suggestions will help!
You have to put globbing characters outside of quotes for them to be interpreted.
Try instead:
mv -f *"$log"* …
The shell will still keep the resulting matches as one word, so this is OK even if the filenames have spaces.

Adding text into a created file

I'll try and explain my issue as easy as possible.
I have made a script which unzips a file and then takes the data from the resulting files and sorts them into appropriate folders. I am now struggling with one specific part.
My script needs to output a file that contains a label for each directory and the files need to be sorted in reversible order. So far I have this:
#firstly changes to correct directory and then creates a file that contains a list of all the files in that directory sorted by size order
cd processFiles/$type1
ls -S > orderSize1.txt
cd ../$type2
ls -S > orderSize2.txt
cd ../$type3
ls -S > orderSize3.txt
cd ../misc
ls -S > orderSize4.txt
#lists file types by reverse alphabetical order
cd ../$type1
ls -r > tempfile1.txt
cd ../$type2
ls -r > tempfile2.txt
cd ../$type3
ls -r > tempfile3.txt
cd ../misc
ls -r > tempfile4.txt
So in the file I need to have it listed reverse alphabetically (which is done in my script already) but how do I put in comments saying 'these are the jpg files' or 'these are all the gif files.'?
I also need to write a separate clean up script for this, but I think that is quite easy - not too sure on it though.
Thanks for your help!
This assumes you're using bash. Other shells may do things a little differently.
As karakfa noted in a comment, you can use the echo command along with redirection to print a message to a file. For example:
echo "These are the jpeg files." > jpegfiles.txt
Then, when you run your ls command, you would use append redirection to add the results to the file:
ls -r >> jpegfiles.txt

copy multiple files from directory tree to new different tree; bash script

I want to write a script that do specific thing:
I have a txt file e.g.
from1/from2/from3/apple.file;/to1/to2/to3;some not important stuff
from1/from2/banana.file;/to1/to5;some not important stuff
from1/from10/plum.file;/to1//to5/to100;some not important stuff
Now i want to copy file from each line (e.g. apple.file), from original directory tree to new, non existing directories, after first semicolon (;).
I try few code examples from similar questions, but nothing works fine and I'm too weak in bash scripting, to find errors.
Please help :)
need to add some conditions:
file not only need to be copy, but also rename. Example line in file.txt:
from1/from2/from3/apple.file;to1/to2/to3/juice.file;some1
from1/from2/banana.file;to1/to5/fresh.file;something different from above
so apple.file need to be copy and rename to juice.file and put in to1/to2/to3/juice.file
I think thaht cp will also rename file but
mkdir -p "$to"
from answer below will create full folder path with juice.file as folder
In addidtion after second semicolon in each line will be something different, so how to cut it off?
Thanks for all help
EDIT: There will be no spaces in input txt file.
Try this code..
cat file | while IFS=';' read from to some_not_important_stuff
do
to=${to:1} # strip off leading space
mkdir -p "$to" # create parent for 'to' if not existing yet
cp -i "$from" "$to" # option -i to get a warning when it would overwrite something
done
Using awk
(run the awk command first and confirm the output is fine, then add |sh to do the copy)
awk -F";" '{printf "cp %s %s\n",$1,$2}' file |sh
Using shell (get updated that need manually create folder, base on alfe's
while IFS=';' read from to X
do
mkdir -p $to
cp $from $to
done < file
I had this same problem and used tar to solve it! Posted here:
tmpfile=/tmp/myfile.tar
files="/some/folder/file1.txt /some/other/folder/file2.txt"
targetfolder=/home/you/somefolder
tar --file="$tmpfile" "$files"​
tar --extract --file="$tmpfile" --directory="$targetfolder"
In this case, tar will automatically create all (sub)folders for you! Best,
Nabi

Create symbolic link with dependency to other files

I know my topic is a little confusing, but here is what I want to do.
I have a file which I would like to create a link to in my home directory ~/bin, but when I execute the file that is symbolically linked, the file requires another file in its directory. Therefore, it fails to run because it cannot find the other file. What can I do?
Well, you have two simple solutions.
edit the shell script to point to the absolute path of the file, not just the the basename.
./path/to/file.sh
VS
file.sh
so something like this should do what your after. sed -i 's|file.sh|./path/to/file.sh|g' ~/bin/script.sh it searches your symlinked file, script.sh in this case, and replaces the call to file.sh to ./path/to/file.sh. note you often see sed use /'s. but it can use just about anything as a delimiter, if you wish to use /'s here you will need to escape them. /. you may want to consider escaping the . (period) as well, but in this case its not necessary. If you are new to sed realize that the -i flag means it will edit the file in place. Lastly, realize its a simple search and replace operation and you may chose to do it by hand.
The second way is to create a ln -s to the file as you did with the other file so there exists a symbolic link between both files.
ln -s /far/off/script.sh ~/bin/script.sh
and
ln -s /far/off/file.sh ~/bin/file.sh
more on symlinking
I would rather create a script file in ~/bin/` that calls your executable from the appropriate directory.
Here is an example using /sbin/ifconfig:
$ cat > ~/bin/file
#!/bin/bash
file=/sbin/ifconfig
cd `dirname $file`
`basename $file`
(ctr+d)
$ chmod +x ~/bin/file
$ file
Here you should see the output of ifconfig but the point is: its get executed from the /sbin directory. So if ifconfig had dependencies it would work properly. Just replace /sbin/ifconfig with your absolute path.
Alternatively, you can modify your script as
pushd ~/bin
##### your script here
popd
Combination of readlink and dirname will get the actual directory of the script:
my_dir=$(dirname "$(readlink -f "$0")")
source "$my_dir/other_file"

Resources