how to write while loop for file in google shell to plus 3 for each line - bash

enter image description here
hello, this is a file I created in google shell. I want to plus three for each line such as the first line will be 699 from 696. I tried to use "while read line; do c="line" c=c+3 "line"; done

You can use the following script:
#!/bin/bash
while read -r line || [[ -n "$line" ]]; do
echo $(($line+3));
done < "$1"
After creating it you need to give execution permission to your user:
chmod u+x my_script.sh
before calling it in the following way:
./my_script.sh file.in > file.out
the result will be saved in the file.out.
Good luck!
TODO
Error management when you do have a line that is not a number, or contains other characters.

Related

Using Vim commands in a Bash Script

so im trying to create a bash script that runs on MAC command line to a remote server and uses some mv commands to move some files around but i also need it to open up a file and add a line to the top of the file and save it in the middle of the script heres what i have so far:
(this is adjusting permissions so i can edit the file)
chef-client -r xxxxxxredactedxxxxxxredacted
cd /xxx/postgresql/xx/main/
Sudo chmod -R 775 filenamehere
sudo chown -R postgres:postgres filenamehere
read -p 'Enter the IP: ' ip
echo "Enter the file name :"
read -r filename
echo "Type this below: host all all "$ip"/24 trust : "
read -r line
cd /etc/postgresql/12/main/
printf '1i\n%s\n.\nwq\n' "$line" | ed "$filename". <-- **this is the problem line**
^ this command gives me permission denied because of access, for some reason i can edit it with vim but not this command
its worth noting these commands arent ran through my pc so my ability to move files is somewhat limited, its ran through SSM ing into an IP of a test enviroment through my command line
Normally I manually VIM into the file and add a line to the top
Don't know if you're using echo to output the prompts because you didn't know about the -p read option or you wanted the new lines.
You could use command grouping to add a line at the top of your file.
read -p "Have you copied a file to the data shipper? (yes/no)"
if [ "$REPLY" == "yes" ]; then
read -p "Enter a variable: " VARIABLE
read -p "Enter a file name: " FILE
cd /var/xxxredacted////
cd /tmp/
sudo mv "$FILE" /varxxxredactedxxxxxxxx/drop
cd /var/redactedxxxxredactedxx/drop
sudo unzip "$FILE"
fi
read -p "Enter the file name:\n" FILENAME
read -p "Enter the line to be added:\n" LINE
{ echo $LINE; cat "$FILENAME"; } > "${FILENAME}.new"
mv "$FILENAME"{.new,}
sed could be used too, if the line had to go to a specific line :
# If \n is omnited, $LINE will just be inserted on
# line 1 instead of appending a new line
sed -i "${LINENB}s/$LINE\n/" $FILENAME

Loop history commands from first to 10 using Bash terminal

I'm should use until loop to get first 10 commands from history line by line.
Tried something like:
counter=0
until [ $counter -gt 10 ]
do
echo !$counter
((counter++))
done
But output is docounter ten times.
The main issue is how to get inside loop specific line from history.
Csh-style history expansion is an interactive feature; it does not work in scripts.
It's looking like you are simply looking for history $HISTSIZE | head -n 10
There are a few simple ways. Try this -
while read -r cmd; do if ((ctr++ < 10)); then echo "$cmd"; fi; done < "$HISTFILE"
or
history|head -10|mapfile -t h && for c in {0..9}; do echo "${h[c]}"; done
edit
The terminal you are using at tutorialspoint kinda sucks.
Try it this way, and pay attention to why it matters.
history | while read -r cmd; do if ((ctr++ < 10)); then echo "$cmd"; fi; done
Specifically, bash: /tmp/.bash_history: Permission denied
They are apparently only allowing access to the history file through the history program.

how to read values from a file inside gitlab-ci yml

Trying to read values from a file inside gitlab-ci.yml file:
#!/usr/bin/bash
- IN_FILE="base_dir/apps_namespaces.txt"
- echo "IN_FILE = " > $IN_FILE
- while IFS= read -r line || [ -n "$line" ]; do
- echo "Name read from file - " > $line
- done < $IN_FILE
But this script fails with error - "/usr/bin/bash: line 131: read: line: invalid number"
Whereas same logic works in a plain script file, having following code:
#!/bin/bash
while IFS= read -r line || [[ -n "$line" ]];
do
echo "Text read from file: $line"
done < "$1"
when ran this script using command : ./scrpt apps_namespaces.txt
it rans and print each line.
What can be done if needs a long list to be read inside a gitlab-ci yml ?
Check if you can emulate this gitlab-ci.yml loop example, which:
does not include the shebang (#!/bin/bash)
does not have a - in front of each line
script:
[...]
- while read line; do
echo $line;
./sireg-linux exec --loader-sitemap-sitemap \"$line\" >> ./output/${line##*/}_out.txt;
done < sitemap-index
Of course, the alternative is to put the logic in a script, called from the pipeline, as documented in gitlab-org/gitlab-runner issue 2672
This is basic Unix, you just need your script to be executable in your git repo
chmod a+x scripts/test.sh
git add scripts/test.sh
git commit "fixing permissions"
git push
don't put /usr/bin/env for sh nor bash: both are 100% guaranteed to be present as #! /bin/sh or /bin/bash if bash is installed, or at least a much guaranteed to be there than /usr/bin/env to exists (and using env sh is not very good security)
A better approach which I followed:
put the logic to read file contents inside a script file. And refer this script inside gitlab-ci.yml worked.
It is cleaner and manageable.

Bash loop to read line by line and create folder by line index

I am trying to do the following in a bash file:
mybash.sh myinputfile.txt myloopfile.csv
Create a for loop, that reads myloopfile.csv line by line, and then creates a folder which will take the line number as the folder name prefixed to "folder", ex. folder1, folder2...
and then inside this folder$i create a folder called input and another called output.
write the line$i content into a file called myline.txt and put this file inside the folder$i/input
and copy the file myinputfile.txt that i will pass as a parameter to the bash file inside the folder$i/input as well.
and then run my personal script that takes two arguments:
python myscript.py -i ./folder$i/input -o ./folder$i/output
and done!
myfile.csv
101,1001,10012,100121
102,101213,11122.1,12.15
103,122.15,155.2,1515.54
104,154.4,4551.1,454
what I currently have:
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
mkdir ./folder$line
echo "$line" >> Folder$line/input/myline.txt;
cp myinputfile.txt Folder$line/input
python myscript.py -i ./folder$i/input -o ./folder$i/output
done < "$1"
the problem is that I can't get the line index to pass it as a suffix to the folder name, so I currently get the line content.and I don't know how to read the two files from the arguments that i pass to the mybash.sh.
Use a counter to keep track of line numbers:
#!/bin/bash
input_file=$1
csv_file=$2
count=1
while IFS= read -r line || [[ -n "$line" ]]; do
input_dir="./folder$count/input"
output_dir="./folder$count/output"
mkdir -p "$input_dir" "$output_dir"
printf '%s\n' "$line" > "$input_dir/myline.txt"
cp "$input_file" "$input_dir"
python myscript.py -i "$input_dir" -o "$output_dir"
((count++))
done < "$csv_file"

Make script that reads argument from command line

I am running quantum chemical calculations by providing the command molcas -f file.input. I now have need for putting the molcas -f into a script that also tails the last 100 lines of the generated file.log, for me to quickly confirm that everything finished the way it's supposed to. So I want to run the script run.sh:
#!/bin/bash
molcas -f [here read the file.input from command line]
tail -100 [here read the file.log]
The question is how I can make the script read the argument I give, and then find on its own the output file (which has the same filename, but with a different extension).
Follow-up
Say I have a bunch of numbered files file-1, file-2, ..., file-n. I would save time if I instead of running
./run.sh file-1.input file-1.log
I run
./run.sh n n
or
./run.sh n.input n.log
assuming that the actual filename and placement of the number n is given in the script. Can that be done?
With this code:
#!/bin/bash
molcas -f "$1"
tail -100 "$2"
You will need to execute the script run.sh as follows:
./run.sh file.input file.log
to be hornest I have/had no clue over molcas, so I jumed to this side to get basic understandings.
The syntax shoould look like this ...
#!/bin/bash
# waiting for input
read -p "Enter a filename (sample.txt): " FILE
# checking for existing file
if [ -e "$FILE" ]; then
read -p "Enter a command for moculas: " CMD
else
echo "Sorry, \"${FILE}\" was not found. Exit prgramm."
exit 1
fi
# I am not sure how this command works.
# maybe you have to edit this line by your self.
molcas $FILE -f "$CMD"
# checking for programm-errors
ERRNO=$?
if [ "$ERRNO" != "" ] && [ "$ERRNO" -gt 0 ]; then
echo "Molcas returned an error. Number: ${ERRNO}"
exit 1
fi
# cuts off the fileending (For example: sample.txt gets sample)
FILENAME="${FILE%.*}"
# checking other files
ERRFILE="${FILENAME}.err"
tail -n 100 $ERRFILE
LOGFILE="${FILENAME}.log"
tail -n 100 $LOGFILE
exit 0
I would have posted more, but its not clear what to do with this data.
Hope this helps a bit.

Resources