I've some image files generated by an analysis. Every time I do analysis, the file names are same. And I've to create a presentation, and I'm using Libre Office Impress.
Let us say, I've three images image1.png, image2.png, and image3.png, and I should put these images say in page no 3, page no 5, and page no 8
Now, I'm inserting images manually. I know very basic shell scripting. So I was wondering what would be the bash shell script to automatically create an libre office impress file with images automatically inserted at pages mentioned as above.
If the main part of the .odp file doesn't change, it is possible to make a template in flat openDocument format, where the names of the 3 images are updated by script.
A flat document is a uncompressed xml document that can be open with a text editor to change some part manually with caution. Usually the name of such a document is rather with the .fodp You must save this template in flat format, with links to the images rather than incorporate them.
So.
Let us say :
the template is at /path/to/the/template.fodp beside the images im1.png, img2.png, img3.png of the example.
the name of the first image is image1.png, the second image2.png, and the third : image3.png.
the images to be imported are in the same directory /path/to/the/document where will be the final document.
Let us write a script insertImages.sh
myTpl="$1" # will contains '/path/to/the/template.fodp'
myDir="$2" # will contains '/path/to/the/document'
img1="$3" # will contains the name of the first image in myDir
img2="$4" # will contains the name of the second image in myDir
img3="$5" # will contains the name of the third image in myDir
[[ -f "$1" ]] && cp "$1" "$2/document.fodp" || exit 1 # checks if the template exists and copy it
[[ -f "$3" ]] && sed "$2/document.fodp" "s/img1.png/$3/" || exit 1 # overwrite the name of the first image
[[ -f "$4" ]] && sed "$2/document.fodp" "s/img2.png/$4/" || exit 1 # overwrite the name of the second image
[[ -f "$5" ]] && sed "$2/document.fodp" "s/img3.png/$5/" || exit 1 # overwrite the name of the third image
This script should be invoked this way :
insertImages.sh "/path/to/the/template.fodp" "/path/to/the/document" "image1.png" "image2.png" "image3.png"
I'm not a big programmer. So there is probably some mistakes in those lines. But the principle is there.
They are some constaints :
a flat document
relative pathes to the images.
Related
I've done a small amount of bash scripting. Mostly modifying a script to my needs.
On this one I am stumped.
I need a script that will read a sub-folder name inside a folder and make a numbered list of folders based on that sub-folder name.
Example:
I make a folder named “Pictures”.
Then inside I make a sub-folder named “picture-set”
I want a script to see the existing sub-folder name (picture-set) and make 10 more folders with sequential numbers appended to the end of the folder names.
ex:
folder is: Pictures
sub-folder is: picture-set
want to create:
“picture-set-01”
“picture-set-02”
“picture-set-03”
and so forth up to 10. Or a number specified in the script.
The folder structure would look like this:
/home/Pictures/picture-set
/home/Pictures/picture-set-01
/home/Pictures/picture-set-02
/home/Pictures/picture-set-03
... and so on
I am unable to tell the script how to find the base folder name to make additional folders.
ie: “picture-set”
or a better option:
Would be to create a folder and then create a set of numbered sub-folders based on the parent folder name.
ex:
/home/Songs - would become:
/home/Songs/Songs-001
/home/Songs/Songs-002
/home/Songs/Songs-003
and so on.
Please pardon my bad formatting... this is my first time asking a question on a forum such as this. Any links or pointers as to proper formatting is welcome.
Thanks for the help.
Bash has a parameter expansion you can use to generate folder names as arguments to the mkdir command:
#!/usr/bin/env bash
# Creates all directories up to 10
mkdir -p -- /home/Songs/Songs-{001..010}
This method is not very flexible if you need to dinamically change the range of numbers to generate using variables.
So you may use a Bash for loop and print format the names with desired number of digits and create each directory in the loop:
#!/usr/bin/env bash
start_index=1
end_index=10
for ((i=start_index; i<=end_index; i++)); do
# format a dirpath with the 3-digits index
printf -v dirpath '/home/Songs/Songs-%03d' $i
mkdir -p -- "$dirpath"
done
# Prerequisite:
mkdir Pictures
cd Pictures
# Your script:
min=1
max=12
name="$(basename "$(realpath .)")"
for num in $(seq -w $min $max); do mkdir "$name-$num"; done
# Result
ls
Pictures-01 Pictures-03 Pictures-05 Pictures-07 Pictures-09 Pictures-11
Pictures-02 Pictures-04 Pictures-06 Pictures-08 Pictures-10 Pictures-12
I have two folders: control and patients both with several folders inside, belonging to one individual each.
I want to do two things:
Create inside the folder for each individual a new folder called cortical_maks and inside that one, three more, called accumebens, putamen, caudate
Inside each individual folder, there are images in img format I want to convert to nii.gz using the funtion fslchfiletype.
This is what I have so far:
DIR="/media/Roy"; cd "$DIR/Analysis"
for group in Controls Patients; do
for case in $group/*; do
[ -d $case ] || continue #if its not a folder
mkdir $DIR/Analysis/$case/Cortical_masks && cd $_
mkdir accumbens putamen caudate
for file in $DIR/Analysis/$case/ROIS2/rs_roi/*.img; do
fslchfiletype NIFTI_GZ "$file"
done;
done;
done;
There are two problems with this code.
The second time you run it, the folder cortical masks is created in the main folders, that is controls and patients, that is, outside the folder it´s supposed to work.
Also, it just converts img to niig.gz for one folder at a time. First time you execute the script, converts imgs for the folder belonging to the first individual, etc
Question 01 :
The second time you run it, the folder cortical masks is created in the main folders, that is controls and patients. I want it in a way that doesn´t create new folders if there is already one with the same name.
I suggest you to use an if loop to verify if the folder cortical_mask exist before to run your code :
#check if the folder exist, if yes = true so we add ! caracter to have the opposite
if [ ! -d "$DIR/Analysis/$case/Cortical_masks" ]
then
#Your code
fi
Question 02 :
Also, it just converts img to niig.gz for one folder at a time. First time you execute the script, converts imgs for the folder belonging to the first individual, etc
If you want to do two actions in the same time, why do you not create two bash scripts and execute them simulteanously ? Or, you can automate them by creating a process in your OS which will execute scripts for you.
I have a dataset contains ( .csv files and images ) but I have some images are not annotated, that means the number of images < number of .csv files.
I have placed all images to the folder that contains the .csv files.
I would like to know if is it possible to delete additional images ( images without annotations, I mean images without a correspondent .csv files ) with a shell script or command line?
I solved my problem by this command:
for f in .jpg; do [[ -f ${f%.}.csv ]] || echo "$f"; done
The Source of the solution:
linux- Script to compare and delete the files
I am new to unix and could really use your help.
I want to rename a lot of photographs so they correspond with codes of items that are on the picture. I have a .csv file that has the original .jpg name and then the codes I want the photos to be renamed to, following in consecutive columns. For example:
IMG_1234.JPG,AB001,AB003,AB004
IMG_1345.JPG,AB011,AB012,AB013,AB014,AB015
IMG_1456.JPG,AB112
IMG_1678.JPG,AB125,AB126
So I want IMG_1234.JPG copied 3 times and renamed to AB001, AB003, and AB004 etc.
I know I need a script and that I can copy and rename files, but I can't figure out how to make a script run through the csv file and copy & rename the .jpg to the names following until an empty cell and then move on to the next row and copy & rename that .jpg etc etc.
I hope my question is clear and I apologize for my limited knowledge.
Thanks in advance!
edit: The image names have directories (with spaces) in front of them as the photographs are in different folders. For example:
./Photos sorted/Samples1-100/IMG_1134.JPG
This should do what you want. The filename of the csv file is given as parameter to the script. You might adjust the paths inside the copy command, currently everything must be in the same directory. If you are using this on a mac or linux, you can also use "ln -s" instead if "cp" to create a symbolic link to the original file to save disk space.
CSVFILE=$1
cat $CSVFILE |\
while read LINE; do
SPLIT=`echo $LINE | tr "," " "`
FIRST=0
for NAME in $SPLIT; do
if [ $FIRST -eq 0 ]; then
SRCNAME=$NAME
else
DSTNAME=$NAME
cp ${SRCNAME}.jpg ${DSTNAME}.jpg
fi
((FIRST++))
done
done
New to bash scripting here.
I have a folder (/month) which contains more folders (/month/jan, /month/feb, /month/mar etc.) and within these folders there are .txt files (Sales11.txt, Sales17.txt etc.). These text files contain a staff ID number and their sales results as a percentage
e.g Sales11.txt contents are
20456 78
20512 46
20498 67
20645 88
I am looking to search through these .txt files for a Staff ID number and when this exists to make a text file in the staff members folder /staff/20512 (which already exist) by the name Jan.txt or whichever month it has occurred in. The contents of the Jan.txt file will be the name of the sales file and the percent. There could be more than one sales event in each month.
Example output file would be to /staff/20512 the file named Jan.txt which would contain
Sales11 46
Sales17 98
I think I need to include a if loop and use an array to search through the different folders and within this use the grep function to search for the staff id.
I’m not 100% on what order these should be included and how to make use of multiple different arrays in a single script, if that is even possible. My first attempt is below.
while read STAFFID ; do
ARRSTAFF=($STAFFID)
ARRMON=($MONTHS)
ARRSALE=($SALES)
if [ grep -r “/month/${ARRMON}/${ARRSALE}.txt” -e “${ARRSTAFF}” ]; then
echo “${ARRSALE[0]} ${ARRSALE[1]}” >> Staff/${ARRSTAFF[0]}/${ARRMON}.txt
fi
done < contents/Staff.txt
Since there are no staff IDs in the data that fail to appear Staff.txt, the latter provides no additional information. It can be ignored. Every line in every daily report file will correspond to one line in one of the generated per-staff files. It is simpler, then, to read each daily file just once, and to handle all its contents in that run.
Furthermore, it's unclear whether there is any particular advantage to building up arrays in memory. Doing so makes the script more complicated, and that's a lose unless you gain something substantial in return.
Here's one way you could approach the problem:
# keep one level of backups of existing target files
for file in /staff/*.txt; do
mv "${file}" "${file}.bak"
done
# Process the data files once each
for file in /month/*/*.txt; do
# extract relevant filename parts
month=$(basename $(dirname "${file}"))
filebase=$(basename "${file%.txt}")
# read and report out all the lines of the file
while read staffid value; do
echo "$filebase" "$value" >> "/staff/${staffid}/${month}.txt"
done < "$file"
done
That assumes primarily that the daily report files are formatted as you describe, with no extra fields and no whitespace within the fields. It does not rely on Staff.txt at all.