How can I delete multiple characters in my bash script? - linux

I want to create a bash script on Linux, which will only tell me my ip-adress, netmask and broadcast. Right now it shows more than that though, so I would like to remove a specific number of characters from my variable.
Example:
What I have
ip=Hello world!
What I want
ip=Hello
So how can I remove a specific amount of characters from the back of the variable?
I tried multiple things that I found online, but couldn't get it working the way I want it to.

with bash's substring extraction:
$ my_var="Hello world!"
$ my_var=${my_var:0:-6}
$ echo $my_var
Hello

You could pipe through grep and only output the matching portion
echo "ip=hello world" | grep -o "ip=\w*"
Output: ip=hello

Another point is you can use sed command.
For, example
$ my_var="Hello world"
$ my_var=$(echo $my_var | sed -e 's/ .*//')
$ echo $my_var
Hello
or another approach using cut
$ my_var="Hello world"
$ my_var=$(echo $my_var | cut -d ' ' -f1)
$ echo $my_var
Hello
Important - do not type ! symbol in double-quotes

Related

Grep special character #‘

trying to grep "#‘om" but not able to escape or account for the quote char. I tried grep -F, grep -e, grep -n or simply grep "#\‘om" to no avail.
That quote is not the simple quote character it appears to be. It's not clear whether copying-and-pasting the quote character from this website is accurate.
$ echo '‘' | cat -v
M-bM-^#M-^X
$ echo '‘' | xxd
$ 00000000: e280 980a ....
So, it appears the problem is one of character sets.
Note, however, that the following works for me:
$ echo '‘' | grep -F '‘'
‘
As does the following:
$ echo '#‘om' | grep -F '#‘om'
#‘om
It would help to see exactly what is being tried. Perhaps use xxd to confirm what bytes are making up that quote.

using sed to set a variable works on command line, but not bash script

I have looked quite a bit for answers but I am not finding any suggestions that have worked so far.
on command line, this works:
$ myvar=$( cat -n /usr/share/dict/cracklib-small | grep $myrand | sed -e "s/$myrand//" )
$ echo $myvar
$ commonness
however, inside a bash script the same exact lines just echoes out a blank line
notes - $myrand is a number, like 10340 generated with $RANDOM
cat prints out a dictionary with line numbers
grep grabs the line with $myrand in it ; e.g. 10340 commonness
sed is intended to remove the $myrand part of the line and replace it with nothing. here is my sample script
#!/bin/bash
# prints out a random word
myrand=$RANDOM
export myrand
myword=$( cat -n /path/to/dict/cracklib-small | grep myrand | sed -e "s/$myrand//g" <<<"$myword" )
echo $myword
Your command line code is running:
grep $myrand
Your script is running:
grep myrand
These are not the same thing; the latter is looking for a word that contains "myrand" within it, not a random number.
By the way -- I'd suggest a different way to get a random line. If you have GNU coreutils, the shuf tool is built-to-purpose:
myword=$(shuf -n 1 /path/to/dict/cracklib-small)
#!/bin/bash
# prints out a random word
myrand=$RANDOM
export myrand
myword=$( cat -n /path/to/dict/cracklib-small | grep myrand | sed -e "s/$myrand//g" <<<"$myword" )
echo $myword
where is the $ sign in grep myrand ?
you must put in some work before posting it here.

String concating using linux pipe

Script:
env|grep JAVA_HOME|cat >>aa.txt
aa.txt will get values: JAVA_HOME=...
How can I script to get values as: export JAVA_HOME=...
This script is wrong:
env|grep JAVA_HOME|cat 'export'$0>>aa.txt
You can use this command to get the required output
$ env | grep JAVA_HOME | sed 's/.*/export &/' | cat >> aa.txt
.* represent anything from the output
& represent all in the first field of .*.
You can use awk utility:
env|grep JAVA_HOME|awk '{print "export "$0;}'|cat >> aa.txt
$0 - means printing all the input columns (default column separator is space)
For the general case, including the possibility of more than one matching line for the grep and that you might want to do complex work on each line, you can feed a pipe to a loop:
env | while read line; do echo "export ${line}"; done
Alternatively, you could use sed:
env | sed "s/^/ export/"
(^ indicating start-of-line.)

How do I replace : characters with newline?

I looked at a very similar question but was unable to resolve the issue Replace comma with newline in sed
I am trying to convert : characters in a string. This is what I tried:
echo -e 'this:is:a:test' | sed "s/\:/'\n'/g"
but this replaces : with n. I tried tr too but had the same result. I believe the -e is not seen after being piped so new line is not recognized.
Any help is appreciated.
echo 'this:is:a:test' | tr : \\n
Any POSIX-compliant tr will support the \n escape sequence. You need to take care to quote or escape the escape sequence, however (double backslash above).
The -e argument to echo has no effect on your argument to echo.
I'll presume that you have the string in a variable already. This uses the parameter expansion substitution operator to replace every : with a newline, which is specified using a $'...'-quoted string. Both features are bash extensions to the standard, and may not work in another shell.
$ foo="this:is:a:test"
$ bar="${foo//:/$'\n'}"
$ echo "$bar"
this
is
a
test
Perhaps Perl is an option?
echo -e 'this:is:a:test' | perl -p -e 's/:/\n/g'
You do not need echo -e because you have \n in sed, not in echo statement.
So, the following should work (note that I have changed '\n' to \n):
echo -e 'this:is:a:test' | sed "s/\:/\n/g"
or
echo 'this:is:a:test' | sed "s/\:/\n/g"
Also note that you do not need to escape : so the following will work too (thanks to #anishsane)
echo 'this:is:a:test' | sed "s/:/\n/g"
Below is just to reiterate why you need -e for echo
$ echo -e "hello \n"
hello
$ echo "hello \n"
hello \n
If Python is an option:
echo 'this:is:a:test' | python3 -c 'print(input().replace(":", "\n"))'
output:
this
is
a
test

Grep Syntax with Capitals

I'm trying to write a script with a file as an argument that greps the text file to find any word that starts with a capital and has 8 letters following it. I'm bad with syntax so I'll show you my code, I'm sure it's an easy fix.
grep -o '[A-Z][^ ]*' $1
I'm not sure how to specify that:
a) it starts with a capital letter, and
b)that it's a 9 letter word.
Cheers
EDIT:
As an edit I'd like to add my new code:
while read p
do
echo $p | grep -Eo '^[A-Z][[:alpha:]]{8}'
done < $1
I still can't get it to work, any help on my new code?
'[A-Z][^ ]*' will match one character between A and Z, followed by zero or more non-space characters. So it would match any A-Z character on its own.
Use \b to indicate a word boundary, and a quantifier inside braces, for example:
grep '\b[A-Z][a-z]\{8\}\b'
If you just did grep '[A-Z][a-z]\{8\}' that would match (for example) "aaaaHellosailor".
I use \{8\}, the braces need to be escaped unless you use grep -E, also known as egrep, which uses Extended Regular Expressions. Vanilla grep, that you are using, uses Basic Regular Expressions. Also note that \b is not part of the standard, but commonly supported.
If you use ^ at the beginning and $ at the end then it will not find "Wiltshire" in "A Wiltshire pig makes great sausages", it will only find lines which just consist of a 9 character pronoun and nothing else.
This works for me:
$ echo "one-Abcdefgh.foo" | grep -o -E '[A-Z][[:alpha:]]{8}'
$ echo "one-Abcdefghi.foo" | grep -o -E '[A-Z][[:alpha:]]{8}'
Abcdefghi
$
Note that this doesn't handle extensions or prefixes. If you want to FORCE the input to be a 9-letter capitalized word, we need to be more explicit:
$ echo "one-Abcdefghij.foo" | grep -o -E '\b[A-Z][[:alpha:]]{8}\b'
$ echo "Abcdefghij" | grep -o -E '\b[A-Z][[:alpha:]]{8}\b'
$ echo "Abcdefghi" | grep -o -E '\b[A-Z][[:alpha:]]{8}\b'
Abcdefghi
$
I have a test file named 'testfile' with the following content:
Aabcdefgh
Babcdefgh
cabcdefgh
eabcd
Now you can use the following command to grep in this file:
grep -Eo '^[A-Z][[:alpha:]]{8}' testfile
The code above is equal to:
cat testfile | grep -Eo '^[A-Z][[:alpha:]]{8}'
This matches
Aabcdefgh
Babcdefgh

Resources