How to loop script till user input is empty? - shell

I am trying to make my script to repeat till the user leaves the block question empty. I just got the loop to run, but I can not find a way to make it possible to stop it when block is empty.
I hope some one can help me!!
#!/bin/tcsh -f
#
set word="start"
until ($word !=""); do
#First ask for Compound and Block Name.
echo -n "please enter block name: "
read block
echo -n "please enter compound name: "
read compound
#Now coping template with new name
#
cp Template $block
#
for line in `cat $block`;do
echo $line | sed -e "s/test1/${block}/g" -e "s/test2/${compound}/g" >>./tmp124.txt
done
mv ./tmp124.txt $block
done

Do you want to use bash or csh? You are using bash syntax but tagged your question csh and call tcsh in the first line of your code.
To answer your question, here are examples of how to iterate on standard input until some input is empty:
For tcsh:
#!/bin/tcsh
while ( 1 )
set word = "$<"
if ( "$word" == "" ) then
break
endif
# rest of code...
end
For bash:
#!/bin/bash
while read word; do
if [ -z $word ]; then
break
fi
# rest of code...
done

Use "Until do" loop,
Eg :
For session variable i am assigning default value, Then entering loop. User can pass any value on each prompt when the value is empty, Loop will Terminate and exit the script.
session="Mysession"
until [$session -eq $null]
do
echo $session
echo "Leave Blank to Terminate session"
read -p "Enter session name : " session
done
echo "Exiting.."

Related

How can I read user input in a Bash script? [duplicate]

This question already has answers here:
How do I read user input into a variable in Bash?
(6 answers)
Closed 4 years ago.
Using Bash, I tried to read input from the user like this:
#!/bin/bash
function read_from_user {
cat | echo
}
echo 'Do you want to create the folder "new.folder" ?'
var=`read_from_user`
if [[ ${var} == yes ]]; then
mkdir new.folder
fi
echo 'var is: ${var}'
But it's not working, var is empty, even though the user input is not empty.
How can I read user input from my Bash script?
You should use read:
#!/bin/bash
echo 'Do you want to create the folder "new.folder" ?'
read var
if [[ "$var" == "yes" ]]; then
mkdir new.folder
fi
echo "var is: $var"
If you really want to use cat, you could do this, as cat without any argument reads from stdin:
#!/bin/bash
echo 'Do you want to create the folder "new.folder" ?'
var=$(cat)
if [[ "$var" == "yes" ]]; then
mkdir new.folder
fi
echo "var is: $var"
However, you would have to use CTRL + D to send on EOF to your program after typing your input. Otherwise cat will wait for more. read is a cleaner way to ask a user for input.
Your code is almost correct, you just need to change your function to read user input into a variable call var. Also you need to change your code in two place. One in the function and one at the place where you are calling your function. I have modified your code like below:-
#!/bin/bash
function read_from_user {
read -r var #here you are reading user input to variable `var`
}
echo 'Do you want to create the folder "new.folder" ?'
#var=`read_from_user`
read_from_user #here you are calling the function to read user input
if [[ ${var} == yes ]]; then
mkdir new.folder
fi
echo "var is: ${var}"
Also always compare two string like if [[ "${var}" == "yes" ]]; but still your above if condition will also work perfectly.
Also best way to do it like below where you don't need a separate echo statement and input will be read at the end out output message:-
#!/bin/bash
function read_from_user {
read -p 'Do you want to create the folder "new.folder" ? ' var
}
#echo 'Do you want to create the folder "new.folder" ?'
#var=`read_from_user`
read_from_user
if [[ "${var}" == "yes" ]]; then
mkdir new.folder
fi
echo "var is: ${var}"

How to make multiple search and replace in files via bash

i have script. In this script i made search and replace of words. Word by word until word 'end'. It is ok and it works. You can see body of my script:
#!/bin/bash
end=end
until [ "$first" = "$end" ];do
echo "please write first word";
read first
if grep -q "$first" *txt; then
echo "word is exists"
grep "$first" *txt
echo "please write second word";
read second
sed -i 's/'"$first"'/'"$second"'/g' *txt
else
echo "second word does not exists"
exit 1
fi
done
It works for me. I have in the result console, where I can endlessly loop words, but if i want to do something like this: How can i write multiple words in line.
For example: "dog" "cat" "fish"
And search and replace all of these words. How can do it? For example, if i need to replace on these words ("elephat" "mouse" "bird"). How can you do it?
I mean search and replace words, like arguments.
You just need a loop to process the arguments.
Assuming you run the script passing pairs of original replacement words (myscript.sh original_word1 replacement1 original_word2 replacement2 ...) it would be something like the following:
while [[ $# -gt 1 ]]
do
original="$1"
replacement="$2"
# your code for actually replacing $original with $replacement
shift # discard already processed original arg
shift # discard already processed replacement arg
done
Note that if the user passes a last original word without replacement the script will just ignore it
Your English is rough, but I think you want to be able to prompt for multiple words, and replace them with a new set?
The below code will let you run a program like replace_words one two three and then be prompted for a list of words to replace, e.g. 1 2 3. After that, it exits.
declare -a replace_list=( "$#" ) # get the replace list as passed arguments
echo -n "Enter words to replace with: "; read -ra sub_list
for ((i=0; i < "${#replace_list[#]}"; ++i)); do
if grep -q "${replace_list[$i]}" *txt; then
echo "first word is exists"
sed -i "s/${replace_list[$i]}/${sub_list[$i]}/g" *txt
else
echo "${replace_list[$i]} does not exists"
exit 1
fi
done

Add lines to a document if they do not already exist within the document

I am trying to say, if document does not exist, then create document. Next read each line of the document and if none of the lines match the $site/$name variables, then add the $site/$name variable into the document.
#!/bin/bash
site=http://example.com
doc=$HOME/myfile.txt
if [ ! -f $doc ]
then
touch $doc
fi
read -p "name? " name
while read lines
do
if [[ $lines != $site/$name ]]
then
echo $site/$name >> $doc
fi
done <$doc
echo $doc
echo $site
echo $name
echo $site/$name
echo $lines
Typing test at the read -p prompt the results are
path/to/myfile.txt
http://example.com
test
http://example.com/test
I feel like I should know this but I'm just not seeing it. What am I doing wrong?
If the file is initially empty, you'll never enter the loop, and thus never add the line. If the file is not empty, you'd add your line once for every non-matching line anyway. Try this: set a flag to indicate whether or not to add the line, then read through the file. If you ever find a matching line, clear the flag to prevent the line from being added after the loop.
do_it=true
while read lines
do
if [[ $lines = $site/$name ]]
then
do_it=false
break
fi
done < "$doc"
if [[ $do_it = true ]]; then
echo "$site/$name" >> "$doc"
fi
The following creates the file if it doesn't exist. It then checks to see if it contains $site/$name. If it doesn't find it, it adds the string to the end of the file:
#!/bin/bash
site=http://example.com
doc=$HOME/myfile.txt
read -p "name? " name
touch "$doc"
grep -q "$site/$name" "$doc" || echo "$site/$name" >>"$doc"
How it works
touch "$doc"
This creates the file if it doesn't exist. If it does already exist, the only side-effect of running this command is that the file's timestamp is updated.
grep -q "$site/$name" || echo "$site/$name" >>"$doc"
The grep command sets its exit code to true if it finds the string. If it doesn't find it, then the "or" clause (in shell, || means logical-or) is triggered and the echo command adds the string to the end of the file.

How to use a text file for multiple variable in bash

I want to make an bash script for things I use much and for easy access of things but I want to make an firstrun setup that saves the typed paths to programs or commands in a txt file. But how can I do that. And how can I include the lines of the text file to multiple variables?
After a lot of testing I could use the 2 anwsers given. I need to store a variable directly to a textfile and not asking a user for his details and then stores that to a file
So I want it to be like this
if [[ -d "/home/$(whoami)/.minecraft" && ! -L "/home/$(whoami)/.minecraft" ]] ; then
echo "Minecraft found"
minecraft="/home/$(whoami)/Desktop/shortcuts/Minecraft.jar" > safetofile
# This ^ needs to be stored on a line in the textfile
else
echo "No Minecraft found"
fi
if [[ -d "/home/$(whoami)/.technic" && ! -L "/home/$(whoami)/.technic" ]]; then
echo "Technic found"
technic="/home/$(whoami)/Desktop/shortcuts/TechnicLauncher.jar" > safetofile
# This ^ also needs to be stored on an other line in the textfile
else
echo "No Technic found"
fi
I really want to have an anwser to this because I want to script bash. I already experience in bash scripting.
Here's an example:
#!/bin/bash
if [[ -f ~/.myname ]]
then
name=$(< ~/.myname)
else
echo "First time setup. Please enter your name:"
read name
echo "$name" > ~/.myname
fi
echo "Hello $name!"
The first time this script is run, it will ask the user for their name and save it. The next time, it will load the name from the file instead of asking.
#!/bin/bash
# file to save the vars
init_file=~/.init_vars.txt
# save_to_file - subroutine to read var and save to file
# first arg is the var, assumes init_file already exists
save_to_file()
{
echo "Enter $1:"
read val
# check if val has any spaces in them, you will need to quote them if so
case "$val" in
*\ *)
# quote with double quotes before saving to init_file
echo "$1=\"$val\"" >> $init_file
;;
*)
# save var=val to file
echo "$1=$val" >> $init_file
;;
esac
}
if [[ ! -f $init_file ]]
then
# init_file doesnt exist, this will come here only once
# create an empty init_file
touch $init_file
# vars to be read and saved in file, modify accordingly
for var in "name" "age" "country"
do
# call subroutine
save_to_file "$var"
done
fi
# init_file now has three entries,
# name=val1
# age=val2
# country=val3
# source the init_file which will read and execute commands from init_file,
# which set the three variables
. ${init_file}
# echo to make sure it is working
echo $name $age $country

Shell scripting to print list of elements

Is there any command in shell scripting which is similar to "list" in tcl? I want to write a list of elements to a file (each in separate line) .But, if the element matches a particular pattern then element next to it and the element itself should be printed in the same line. Is there any command in shell script for doing this?
example: my string is like " execute the command run abcd.v"
I want to write each word in separate lines of a file but if the word is "run" then abcd.v and run must be printed in the same line. So, the output should be like,
execute
the
command
run abcd.v
How to do this in shell scripting?
line="execute the command run abcd.v"
for word in $line # the variable needs to be unquoted to get "word splitting"
do
case $word in
run|open|etc) sep=" " ;;
*) sep=$'\n' ;;
esac
printf "%s%s" $word "$sep"
done
See http://www.gnu.org/software/bash/manual/bashref.html#Word-Splitting
Here's how you can do it in bash:
Name this following script as list
Set it to executable
Copy it to your ~/bin/:
List:
#!/bin/bash
# list
while [[ -n "$1" ]]
do
if [[ "$1" == "run" ]]; then
echo "$1 $2"
else
echo "$1"
fi
shift
done
And this is how you can use it on the command prompt:
list execute the command run abcd.v > outputfile.txt
And your outputfile.txt will be written as:
execute
the
command
run abcd.v
You could accomplish it by using the below script. It would not be a single command. Below is a for loop that has an if statment to check for the keyword run. It does not append a new line character( echo -n ).
for i in `echo "execute the command run abcd.v"`
do
if [ $i = "run" ] ; then
echo -n "$i " >> fileOutput
else
echo $i >> fileOutput
fi
done

Resources