My bash script retrieves a list of folders, and stores them under a projectlist parameter.
Later, I want to loop through each folder, using the project name as a variable in the file path. Each project folder contains a ProjectFile.txt file, from which I want to append the contents to a common .csv file.
projectlist=$(./some/project/filepath/projects)
echo ${projectlist[#]}
while read project;
do
while read line;
do
echo "$project" "$line" >> /data/allData.csv
done < ./some/project/filepath/projects/"$project"/ProjectFile.txt
done < $projectlist
What it currently ends up doing however, is printing each individual element in the projectlist, without writing anything to the .csv file. Any idea where the issue lies?
Related
I have 44 RTF files (file1.rtf, file2.rtf, ..., file44.rtf) and I need to combine them all into a single file (either file1.rtf or a new file altogether).
I understand that the way to combine the contents of two files is like this:
cat file2.rtf >> file1.rtf
This example appends the contents of file2.rtf into file1.rtf.
I also understand that I need to iterate through the files, which I can achieve like this:
for file in *.rtf;
do
# do something;
done
As such, I have this which appears to do the job:
#!/bin/bash
for file in *.rtf;
do
cat $file >> "../combined.rtf";
echo "File $file added."
done
But there is an issue: when I run cat ../combined.rtf I see the combined documents but when I run open ../combined.rtf it only shows me the contents of file1.rtf (in LibreOffice Writer).
Where have I gone wrong?
I am having list of xml files in a folder like - data0.xml, data1.xml, data2.xml, ...data99.xml
I have to read the contents of these files for further processing. Currently I am using for loop like below
for xmlentry in `ls -v *.xml
do
execute_loop $xmlemtry
done
This is executing fine for all xml's file in sequence ,
But I wanted to know if I want to force FOR loop to start from data10.xml and proceed till data99.xml
For loop shoud start from data10.xml, data11.xml .... data99.xml
How to do something like this in shell scripting, better if I could
control the start of loop with a variable
You can construct the name of the files and loop through them. In you specific example, something like this could work:
first=10
last=99
for i in $(seq "$first" "$last")
do
xmlfile="data${i}.xml"
execute_loop "$xmlfile"
done
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
I'm writing a unix shell script that sorts data in ten subdirectories (labelled 1-10) of the home directory. In each subdirectory, the script needs to rename the files hehd.output and fort.hehd.time, as well as copy the file hehd.data to a .data file with a new name.
What I'd like it to do is rename each of these files in the following format:
AA.BB.CC
Where
AA = a variable in the hehd.data file within the subdirectory containing the file
BB = the name of the subdirectory containing the file (1-10)
CC = the original file name
Each subdirectory contains an hehd.data file, and each hehd.data file contains the string ij0=AA, where AA represents the variable I want to use to rename the files in the same subdirectory.
For example: When run, the script should search /home/4/hehd.data for the string ij0=2, then move /home/4/hehd.output to /home/4/2.4.hehd.output.
I'm currently using the grep command to have the script search for the string ij0=* and copy it to a new text file within the subdirectory. Next, the string ij0= is deleted from the text file, and then its contents are used to rename all target files in the same subdirectory. The last line of the shell script deletes the text file.
I'm looking for a better way to accomplish this, preferably such that all ten subdirectories can be sorted at once by the same script. My script seems incredibly inefficient, and doesn't do everything that I want it to by itself.
How can I improve this?
Any advice or suggestions would be appreciated; I'm trying to become a better computer user and that means learning better ways of doing things.
Try this:
fromdir=/home
for i in {1..10};do
AA=$(sed 's/ij0=\([0-9]*\)/\1/' "$fromdir/$i/hehd.data")
BB="$i"
for f in "$fromdir/$i/"*;do
CC="${f##*/}"
if [[ "$CC" = "hehd.data" ]]; then
echo cp "$f" "$fromdir/$i/$AA.$BB.$CC"
else
echo mv "$f" "$fromdir/$i/$AA.$BB.$CC"
fi
done
done
It loops over directories using Bash sequence {1..10].
In each directory, with the sed command the ij0 value is assigned to AA variable, the directory name is assigned to BB.
In the file loop, if the file is hehd.data it's copied, else it's renamed with the new name.
You can remove the echo before cp and mv commands if the output meets your needs.
I have a set of files that I would like to rename by using new filenames stored in a txt file. My original files:
7170M
7172M
7187P
7192N
7198P
I would like to add to each filename specific new names so that the above files become:
1956_26_7170M
1962_12_7172M
1989_32_7187P
1986_22_7192N
1943_13_7198P
I created a document new_names.txt containing new filenames and tried the following.
for f in *.txt; do mv "$f" "$new_name"; done < new_names.txt
But it changes only the first filename.
You can only store the new parts of the names in the file (provided you'll process the files in the sorted order):
1956_26
1962_12
1989_32
1986_22
1943_13
Then, iterate over the files, read one line for each of them:
for file in 7* ; do
read new
mv "$file" "$new"_"$file"
done < new_names.txt
Your main problem was than for ... in doesn't read from a file, it iterates over a list given after in. In your case, the list only had one member: new_names.txt. Also, You didn't populate $new_name anywhere.