#!/usr/bin/env zsh
doit() {
if [[ "$2" = "start" ]]; then
for loc in $(cat all-doc); do
if ! screen -list | grep -q My-$loc; then
screen -dmS My-$loc /home/Server -f /home/$loc.cfg
fi
done
elif [[ "$2" = "stop" ]]; then
for loc in $(cat all-doc); do
if screen -list | grep -q My-$loc; then
pkill -f My-$loc;
fi
done
else
echo "Option: ERROR..."
fi
}
nothing() {
if [[ "$2" = "start" ]]; then
echo "Option: 1"
elif [[ "$1" = "stop" ]]; then
echo "Option: 2"
else
echo "Option: 3"
fi
}
case "$2" in
start)
"$1" "$2";
;;
stop)
"$1" "$2";
;;
restart)
restart;
;;
*)
echo "Usage: $0 {doit|nothing} {start|stop|restart}"
exit 1
;;
esac
exit 0
I try to debug my script and this is the debug output with -x option.
Output:
./script.sh:33> case start (start)
./script.sh:35> doit start
doit:1> [[ '' = start ]]
doit:7> [[ '' = stop ]]
doit:14> echo 'Option: ERROR...'
Option: ERROR...
./script.sh:49> exit 0
I dont know why this happend but seems $2 get blank string [[ '' = start ]] and [[ '' = stop ]] im new in shell scripts and im try to do somthing for my game server, i got confuesed.
I'm trying to figure out how to edit this script so it will validate an IP range instead of just one IP, i.e. 192.168.1.0/24.
echo "Target IP Address range or specific IP: "
read IPaddr
#IPv4 Validation
is_ip(){
local ip=$1
if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null;then
for i in 1 2 3 4;do
if [ $(echo "$ip" | cut -d. -f$i) -gt 255 ];then
return 1
fi
done
return 0
else
return 1
fi
}
#Test User-inputted IPv4 Address
is_ip "$IPaddr"
if [[ $? -eq 0 ]]; then
echo "Valid IP address/range"
else
echo "Invalid IPv4"
exit 6
fi
This script seems to do what you want if I've understood your question properly.
#!/bin/bash
locInput="$1"
locIP=${locInput%\/*}
if [[ $locInput = #(*/*) ]];then
locRange=${locInput#*\/}
fi
function is_ip
{
if [[ $locIP == ?([0-9])+([0-9])\.?([0-9])+([0-9])\.?([0-9])+([0-9])\.?([0-9])+([0-9]) ]]; then
locVerif=(${locIP//./ })
for i in ${locVerif[*]}; do
if [[ $i -lt 0 || $i -gt 255 ]]; then
return 1
fi
done
if [[ -n $locRange && ($locRange -lt 0 || $locRange -gt 31) ]]; then
return 1
fi
return 0
else
return 1
fi
}
is_ip
if [[ $? -eq 1 ]]; then
echo "Wrong IP/Range"
else
echo "Good IP/Range"
fi
Hope it can help.
I have been beating my head up about this.
I wanted to loop over a multiline string character by character in bash but was loosing all newlines. First thing I did when i didn't find any obvious error was to run shellcheck on it, it seemed fine with the program.
script.sh:
#!/usr/bin/env bash
transform_single() {
if [[ $# -ne 1 ]]; then
echo 'Error: illegal number of args' 1>&2
fi
equation=''
delim0=0
delim="$1"
while IFS= read -rn1 c; do
if [[ $delim0 -eq 0 ]] && [[ "$c" == "$delim" ]]; then
delim0=1
equation=''
elif [[ $delim0 -ne 0 ]] && [[ "$c" == "$delim" ]]; then
delim0=0
echo -n "$equation" | texmath
elif [[ $delim0 -ne 0 ]]; then
equation="$equation$c"
else
echo -n "$c"
fi
done
}
transform_single '$'
input.txt:
<newlines>
<newlines>
# Hello world!
<newlines>
This is a test string.
<newlines>
invocation:
bash script.sh < input.txt
output:
# Hello world!This is a test string.
excepted output:
The same as in the input file.
Working script
#!/bin/bash
transform_single() {
if (($# != 1)); then echo 'Error: illegal number of args' 1>&2; fi
equation=''
delim0=0
delim="$1"
while IFS= read -r -d $'\0' -n 1 c; do
if ((delim0 == 0)) && [[ "$c" == "$delim" ]]; then
delim0=1
equation=''
elif ((delim0 != 0)) && [[ "$c" == "$delim" ]]; then
delim0=0
echo -n "$equation" | texmath
elif ((delim0 != 0)); then
equation="$equation$c"
else
echo -n "$c"
fi
done
}
transform_single '$'
The issue is that you must set a delimiter to read, a null character, to preserve line feed.
I am using Unix Shell. How to remove newline character between two specific strings.
For example, input is:
CASE when a in ('abcd','bdcdf') then
Shng,
END as xyz
Output should be:
CASE when a in ('abcd','bdcdf') then Shng END as xyz,
Parse the file line for line and remember when you see a CASE or END.
The code beneath uses a short syntax for an if-statement and an echo that suppresses \n by the -n parameter.
incase=0
cat x.sql | while read -r line; do
[[ ${line} = CASE* ]] && incase=1;
[[ ${line} = END* ]] && incase=0
[[ ${incase} = 0 ]] && echo "${line}"
[[ ${incase} = 1 ]] && echo -n "${line} "
done
EDIT:
When you have nested CASEs (like CASE ... CASE ... END ... END) and all
CASEs start on different lines you can count how deep your nested.
incase=0
cat x.sql | while read -r line; do
[[ ${line} = CASE* ]] && (( incase = incase + 1)) ;
[[ ${line} = END* ]] && (( incase = incase - 1))
[[ ${incase} = 0 ]] && echo "${line}"
[[ ${incase} > 0 ]] && echo -n "${line} "
done
# You might want an extra echo here so your last line will finish with a \n
echo
EDIT 2: Often you can avoid cat (look for UUOC). Here the code is better as
incase=0
cat x.sql | while read -r line; do
[[ ${line} = CASE* ]] && incase=1;
[[ ${line} = END* ]] && incase=0
[[ ${incase} = 0 ]] && echo "${line}"
[[ ${incase} = 1 ]] && echo -n "${line} "
done
EDIT:
When you have nested CASEs (like CASE ... CASE ... END ... END) and all
CASEs start on different lines you can count how deep your nested.
incase=0
while read -r line; do
[[ ${line} = CASE* ]] && (( incase = incase + 1)) ;
[[ ${line} = END* ]] && (( incase = incase - 1))
[[ ${incase} = 0 ]] && echo "${line}"
[[ ${incase} > 0 ]] && echo -n "${line} "
done < x.sql
# You might want an extra echo here so your last line will finish with a \n
echo
I have been using a combination of tail, head and grep to print out code that is relavant to me. It helps me find functions and get straight to the point. I do this about 30 to 40 times a day so I thought i'd ask for some assistance on this since I am not good with sh scripting.
The command format I'd eventually like is something like giveme "searchstring" -nn << where nn is the number to give to head. err.. moving on
Below is what I am currently doing
grep -rl searchitem ./
cat ./filename | grep -n searchitem
tail -n +line ./filename | head -numberoflinestodisplay
Example:
jezzy#forum:/var/www/sgs# grep -rl insert_into_selectbox ./
./bin/ext/js/functions_edit.js
./src/ext/js/functions_edit.js
jezzy#forum:/var/www/sgs# cat ./bin/ext/js/functions_edit.js | grep -n insert_into_selectbox
195: for (key in data) insert_into_selectbox(selectbox, data[key], key, 0);
232: insert_into_selectbox(selectbox, data[key], key,1);
273: for (key in data) if (key!="_overload_") insert_into_selectbox(selectbox, data[key], key, 0);
289:function insert_into_selectbox(selectbox,text,value,selected) {
323: insert_into_selectbox(id,right.value,right.value,1);
334: insert_into_selectbox(id,options_right[i].text,options_right[i].value,1);
Then I choose one of the greps that works for me. I do not mind if the bash script does it for all occurrences of grep. It'll teach me to be more specific with my searches.
jezzy#forum:/var/www/sgs# tail -n +289 ./bin/ext/js/functions_edit.js | head -30
function insert_into_selectbox(selectbox,text,value,selected) {
if (text=="" || value=="") return;
var obj = getObj(selectbox);
var index = _selectbox_find(obj, value);
if (index == -1) {
index = obj.options.length;
obj.options[index] = new Option(text,value);
}
if (!obj.multiple && selected) obj.options[index].selected = true;
}
I think I could figure it out if I knew how to get all instances of the items found.
Merci and Thanks
Try this, it should be do what you look for, if I understand it correctly:
# Usage: giveme searchstring [numlines]
find . -type f -exec awk -v n=${2:-10} '
/'"$1"'/ {
printf("==== %s ====\n",FILENAME);
for(i=0;i<n;i++)
{
printf("%4d: %s\n",FNR,$0);
getline
}
}' {} +
You can try this script:
#!/bin/bash
shopt -s extglob
SEARCHDIR_DEFAULT="./"
read -ep "Enter search directory [$SEARCHDIR_DEFAULT]: " SEARCHDIR
[[ $SEARCHDIR =~ ^[[:space:]]*$ ]] && SEARCHDIR=$SEARCHDIR_DEFAULT
for (( ;; )); do
read -p "Enter search item: " SEARCHITEM
read -p "Enter number of lines to display: " NUMLINES
readarray -t MATCHEDFILES < <(exec grep -rl "$SEARCHITEM" "$SEARCHDIR")
echo "Please select a file to search into. Press C to cancel, or X to exit."
select FILE in "${MATCHEDFILES[#]}"; do
if [[ -n $FILE ]]; then
readarray -t MATCHEDLINES < <(exec grep -n "$SEARCHITEM" "$FILE")
echo "Please select starting line."
select LINE in "${MATCHEDLINES[#]}"; do
if [[ -n $LINE ]]; then
LINENUM=${LINE%%:*}
tail -n "+$LINENUM" "$FILE" | head -n "$NUMLINES"
elif [[ $REPLY == [cC] ]]; then
break
elif [[ $REPLY == [xX] ]]; then
break 3
fi
done
elif [[ $REPLY == [cC] ]]; then
break
elif [[ $REPLY == [xX] ]]; then
break 2
fi
done
done
New version:
#!/bin/bash
shopt -s extglob
SEARCHDIR_DEFAULT="./"
NUMLINES_DEFAULT=10
for (( ;; )); do
until
read -ep "Enter search directory [$SEARCHDIR_DEFAULT]: " SEARCHDIR
[[ $SEARCHDIR =~ ^[[:space:]]*$ ]] && SEARCHDIR=$SEARCHDIR_DEFAULT
[[ -d $SEARCHDIR ]]
do
echo "Please enter a valid directory."
done
SEARCHDIR_DEFAULT=$SEARCHDIR
until
read -p "Enter search item: " SEARCHITEM
[[ ! $SEARCHITEM =~ ^[[:blank:]]*$ ]]
do
echo "Please enter a valid search item."
done
until
read -p "Enter number of lines to display [$NUMLINES_DEFAULT]: " NUMLINES
[[ $NUMLINES =~ ^[[:space:]]*$ ]] && NUMLINES=$NUMLINES_DEFAULT
[[ $NUMLINES =~ ^[[:digit:]]+$ && NUMLINES -gt 0 ]]
do
echo "Please enter a valid number of lines."
done
NUMLINES_DEFAULT=$NUMLINES
readarray -t MATCHEDFILES < <(exec grep -rle "$SEARCHITEM" "$SEARCHDIR")
P1="Please select a file to search into. [ENTER = show list again, C = cancel, X = exit]: "
P2="Please select starting line. [ENTER = show list again, C = cancel, X = exit]: "
PS3=$P1
select FILE in "${MATCHEDFILES[#]}"; do
if [[ -n $FILE ]]; then
readarray -t MATCHEDLINES < <(exec grep -ne "$SEARCHITEM" "$FILE")
if [[ ${#MATCHEDLINES[#]} -eq 0 || ! ${MATCHEDLINES[0]} =~ ^[[:digit:]]+: ]]; then
echo "No matching lines were extracted. Perhaps file is a binary."
elif [[ ${#MATCHEDLINES[#]} -eq 1 ]]; then
LINENUM=${MATCHEDLINES[0]%%:*}
echo "----------------------------------------"
tail -n "+$LINENUM" "$FILE" | head -n "$NUMLINES"
echo "----------------------------------------"
else
PS3=$P2
select LINE in "${MATCHEDLINES[#]}"; do
if [[ -n $LINE ]]; then
LINENUM=${LINE%%:*}
echo "----------------------------------------"
tail -n "+$LINENUM" "$FILE" | head -n "$NUMLINES"
echo "----------------------------------------"
elif [[ $REPLY == [cC] ]]; then
break
elif [[ $REPLY == [xX] ]]; then
break 3
fi
done
PS3=$P1
fi
elif [[ $REPLY == [cC] ]]; then
break
elif [[ $REPLY == [xX] ]]; then
break 2
fi
done
done