grep weird behaviour in linux command line [duplicate] - linux

This question already has answers here:
Using the star sign in grep
(12 answers)
Closed 1 year ago.
I have a file test.txt which contains this text data
# cat test.txt
*#=>*#
if I use grep to check if the string is in the file using this way
# grep "*#=>*#" test.txt
#
it returns nothing..
while if I grep a partial string search
# grep "*#=>" test.txt
# *#=>*#
it works correctly ..
Why in the first case do grep return nothing ?

The asterisk is special to grep, it means "the previous token is repeated zero or more times". So >* would match an empty string or > or >> etc.
To match an asterisk, backslash it in the pattern:
grep '\*#=>\*#' test.txt
(The first asterisk follows no token, so the backslash is optional.)

Related

How can I use sed or grep to delete the first line of input if it contains a string? [duplicate]

This question already has answers here:
How do I match multiple addresses in sed?
(4 answers)
Closed 3 years ago.
I am redirecting input and have 2 fields that I extracted from the tail of an XML file, and I need to ignore the first line if it isn't the first of the 2 entries.
tail -n 327 ~/.local/share/recently-used.xbel | grep -e "<bookmark href=" -e "<mime:mime-type type="
Here is the output from that code, which is working fine, but the problem is that the first line is a
<mime:mime-type type="application/x-shellscript"/>
<bookmark href="file:///usr/local/bin/menu_manager.sh" added="2019-09-17T08:33:48Z" modified="2019-09-17T08:33:48Z" visited="2019-09-17T08:33:49Z">
<mime:mime-type type="application/x-shellscript"/>
I need to look at the first line, and if it contains the string
<mime:mime-type type=
then I need to remove that line and pass the rest of the lines on for the next processing step
I tried
sed '1/<mime:mime-type/d'
But is gives me an error:
sed: -e expression #1, char 2: unknown command: `/'
Try
sed '1{/<mime:mime-type/d}'
which uses a block {} which is only run on line 1, with the delete command in the block.
If you are OK with awk you can use this
awk 'NR!=1 || !/<mime:mime-type type=/'
This prints every line that is not the first line (NR!=1) or doesn't match the pattern (!/<mime:mime-type type=/). As there is no action specified, awk uses the default action print.

Substring in linux based on first occurrence [duplicate]

This question already has answers here:
My regex is matching too much. How do I make it stop? [duplicate]
(5 answers)
Closed 5 years ago.
I have a raw unformatted Strings like below in a file.
"],"id":"1785695Jkc","vector":"profile","
"],"id":"jashj24231","vector":"profile","
"],"id":"3201298301","vector":"profile","
"],"id":"1123798749","vector":"profile","
I wanted to extract only the id values like below
1785695Jkc
I tried the below command
grep -o -P '(?<="],"id":").*(?=",")' myfile.txt >new.txt
but that takes the last occurance of the "," like below
1785695Jkc","vector":"profile
but I would need to split on the first occurrence only.
to extract only the id values like above which seem to be alphanumeric strings of length 10, use:
$ awk 'match($0,/[[:alnum:]]{10}/){print substr($0,RSTART,RLENGTH)}' file
1785695Jkc
jashj24231
3201298301
1123798749
If the definition of values like is not correct, please be more specific on the requirement.
Btw, changing your grep a bit works also:
$ grep -o -P '(?<="],"id":")[^"]*'
sed 's/"],"id":"\(.*\)","vector.*/\1/' myfile.txt
that assumes that all lines will start with "],"id":" as your input shows.
Oh, and this is GNU sed btw, your sed may use extended regular expressions, in which case lose the quoting of the brackets.
You can extract just the column you want using cut:
cut -f 2 -d , <filename> | cut -f 2 -d : | tr -d '"'
The first cut will take the id-value pair ("id": "jashj24231") and the second one extracts from that just the value ("jashj24231"). Finally tr removes the enclosing quotes.

I have a requirement of searching a pattern from a file and displaying the pattern only in the screen,not the whole line .How can I do it in linux? [duplicate]

This question already has answers here:
Can grep show only words that match search pattern?
(15 answers)
Closed 5 years ago.
I have a requirement of searching a pattern like x=<followed by any values> from a file and displaying the pattern i.e x=<followed by any values>, only in the screen, not the whole line. How can I do it in Linux?
I have 3 answers, from simple (but with caveats) to complex (but foolproof):
1) If your pattern never appears more than once per line, you could do this (assuming your shell is
PATTERN="x="
sed "s/.*\($PATTERN\).*/\1/g" your_file | grep "$PATTERN"
2) If your pattern can appear more than once per line, it's a bit harder. One easy but hacky way to do this is to use a special characters that will not appear on any line that has your pattern, eg, "#":
PATTERN="x="
SPECIAL="#"
grep "$PATTERN" your_file | sed "s/$PATTERN/$SPECIAL/g" \
| sed "s/[^$SPECIAL]//g" | sed "s/$SPECIAL/$PATTERN/g"
(This won't separate the output pattern per line, eg. you'll see x=x=x= if a source line had 3 times "x=", this is easy to fix by adding a space in the last sed)
3) Something that always works no matter what:
PATTERN="x="
awk "NF>1{for(i=1;i<NF;i++) printf FS; print \"\"}" \
FS="$PATTERN" your_file

Sed - How to switch two words in a line [duplicate]

This question already has answers here:
exchange two words using sed
(5 answers)
Closed 5 years ago.
I'm trying to write a shell script that switches the first and third words in a line. In this case only strings that contain letters (both upper- and lowercase) count as words, everything else (numbers, punctuation, whitespace) is considered whitespace.
For example:
abc123def. ghi...jkl
would turn into:
ghi123def. abc...jkl
I tried the following, but it doesn't work:
sed 's/\([a-zA-Z][a-zA-Z]*\)[^A-Z^a-z]\([a-zA-Z][a-zA-Z]*\)[^A-Z^a-z]\([a-zA-Z][a-zA-Z]*\)/\3 \2 \1/' input.txt
With sed:
$ echo "abc123def. ghi...jkl" | sed -r 's/([A-Za-z]*)([^A-Za-z]*[A-Za-z]*[^A-Za-z]*)([A-Za-z]*)(.*)/\3\2\1\4/g'
$ ghi123def. abc...jkl

How can I get a whole word with grep? [duplicate]

This question already has answers here:
Display exact matches only with grep [duplicate]
(9 answers)
How to make grep only match if the entire line matches?
(12 answers)
Closed 5 years ago.
I want to get the lines that contain a defined word with grep.
Edit: The solution was this one.
I know that I can use the -w option, but it doesn't seems to do the trick.
For example: every word that contains my defined word separated by punctuation signs is included. If I look for dogs, it will show me lines that contain not only dogs word but also cats.dogs, cats-dogs, etc.
# cat file.txt
some alphadogs dance
some cats-dogs play
none dogs dance
few dog sing
all cats.dogs shout
And with grep:
# cat file.txt | grep -w "dogs"
some cats-dogs play
none dogs dance
all cats.dogs shout
Desired output:
# cat file.txt | grep -w "dogs"
none dogs dance
Do you know any workaround that allows you to get the whole word? I've tested it with \b or \< with negative results.
Thanks,
Eudald
Use the word-boundary anchors, in any version of grep you have installed
grep '^dogs$' file.txt
An excerpt from this regular-expressions page,
Anchors
[..] Anchors do not match any characters. They match a position. ^ matches at the start of the string, and $ matches at the end of the string.[..]
Try with -x parameter:
grep -x dogs file.txt
From grep manual:
-x, --line-regexp
Select only those matches that exactly match the whole line. (-x is specified by POSIX.)
NOTE: cat is useless when you pipe its output to grep

Resources