How can I get text using grep command txt that seats between two strings?
for example:
<--string 1-->
the text i need
<--string 2-->
the "the text i need" between the two tags is dynamic, therefor i need a command that will output text from "<--string 1-->" to "<--string 2-->"
This might work for you:
grep -A2 "<--string 1-->" file | grep -v "<--string 1-->\|<--string 2-->"
or
grep -A1 "<--string 1-->" file | grep -v "<--string 1-->"
or in a single process:
sed '/<--string 1-->/,/<--string 2-->/!d;//d' file
or:
awk '/<--string 2-->/{p=0};p;/<--string 1-->/{p=1}' file
Supposing "the text I need" is just one line, you should check that both string1 and string2 appear (Alex's solution only checks one thing).
A better solution would be:
grep -A 2 "string 1" $file | tail -2 | grep -B 1 "string 2" | head -1
if you know that "the text i need" is always above or always below string 1 or string 2, you can use grep -A 1 "string 1" $file | tail -1 or grep -B 1 "string 2" $file | head -1
we need to know what is the line number for string1 and string2
we can use grep -n for that
then using head and tail we can get lines between string1 and string2
for example:
<--string 1-->
the text i need
<--string 2-->
start=$(cat file | grep -n <--string 1--> | grep -Eo [0-9]+)
finish=$cat file | grep -n <--string 2-->) | grep -Eo [0-9]+)
res=$((finish-start))
result=$(cat file | head -$start | tail -$res)
It is a little bit hacky, but it worked for me.
You can use Awk for this.
Inclusive:
awk '/<--string 1-->/,/<--string 2-->/' file
Excluding the string 1 and 2 lines:
awk '/<--string 1-->/{flag=1; next} /<--string 2-->/{flag=0} flag' file
Here, a flag is set when '<--string 1-->' is found in the line, and unset when '<--string 2-->' is found.
You can also keep either the first or second line using:
awk '/<--string 1-->/{flag=1} /<--string 2-->/{flag=0} flag' file
or
awk 'flag; /<--string 1-->/{flag=1} /<--string 2-->/{flag=0}' file
I hope this helps you.
DATA=$(cat /tmp/file)
STARTVAR=$(echo "$DATA" | grep -n '<--string 1-->' | grep -Eo [0-9]+)
ENDVAR=$(echo "$DATA" | grep -n '<--string 2-->' | grep -Eo [0-9]+)
CALC=$((($ENDVAR - $STARTVAR) - 1))
result=$(echo "$DATA" | grep -A $CALC '<--string 1-->')
echo "$result"
Replace the CALC=$((($ENDVAR - $STARTVAR) - 1)) line with CALC=$(($ENDVAR - $STARTVAR)) if you want to include '<--string 2-->' in output
grep word filename
Check grep on wiki.. http://en.wikipedia.org/wiki/Grep
Related
I have a command to grep a file with fullpath that contain a "TypeId: 0", here is the command
grep -rnw /home/username/app/data/store/0/part/.mv -e "TypeId: 0" | awk -F ":" '{print $1}'
and here is the result:
/home/username/app/data/store/0/part/.mv/521/1673332792072/segmentconfig.yaml /home/username/app/data/store/0/part/.mv/521/1673333077920/segmentconfig.yaml /home/username/app/data/store/0/part/.mv/521/1673333077920/segmentconfig.yaml.old /home/username/app/data/store/0/part/.mv/515/1672993850766/segmentconfig.yaml /home/username/app/data/store/0/part/.mv/515/1672993850766/segmentconfig.yaml.old /home/username/app/data/store/0/part/.mv/703/1672987004847/segmentconfig.yaml /home/username/app/data/store/0/part/.mv/703/1672987004847/segmentconfig.yaml.old
Now I confuse how to grep "numofvertice" from each file from that list.
Anyone have an idea to solve this?
You could try this:
grep -rnw /home/username/app/data/store/0/part/.mv -e "TypeId: 0" | awk -F ":" '{print $1}'|xargs -I{} grep "numofvertice" {}
Like this (GNU grep):
<STDIN> | grep -oP '\b\S+\.yaml' | xargs cat
Or with ack:
cd /home/username/app/data/store/0/part/.mv
ack -wl -e "TypeId: 0" | xargs cat
From ack --help:
-l, --files-with-matches
Only print filenames containing matches
How can I print the number of occurrences of "i" in Pneumonoultramicroscopicsilicovolcanoconiosis?
How can I approach this with the commands grep and wc?
echo "Pneumonoultramicroscopicsilicovolcanoconiosis" | grep -o i | wc -l
This should do it:
echo "Pneumonoultramicroscopicsilicovolcanoconiosis"|tr -cd 'i'| wc -c
$ echo "Pneumonoultramicroscopicsilicovolcanoconiosis" | awk '{print gsub(/i/,"")}'
6
(Need in bash linux)I have a file with numbers like this
1.415949602
91.09582241
91.12042924
91.40270349
91.45625033
91.70150341
91.70174342
91.70660043
91.70966213
91.72597066
91.7287678315
91.7398645966
91.7542977976
91.7678146465
91.77196659
91.77299733
abcdefghij
91.7827827
91.78288651
91.7838959
91.7855
91.79080605
91.80103075
91.8050505
sed 's/^91\.//' file (working)
Any way possible I can do these 3 steps?
1st I try this
cat input | tr -d 91. > 1.txt (didnt work)
cat input | tr -d "91." > 1.txt (didnt work)
cat input | tr -d '91.' > 1.txt (didnt work)
then
grep -x '.\{10\}' (working)
then
grep "^[6-9]" (working)
Final 1 line solution
cat input.txt | sed 's/\91.//g' | grep -x '.\{10\}' | grep "^[6-9]" > output.txt
Your "final" solution:
cat input.txt |
sed 's/\91.//g' |
grep -x '.\{10\}' |
grep "^[6-9]" > output.txt
should avoid the useless cat, and also move the backslash in the sed script to the correct place (and I added a ^ anchor and removed the g flag since you don't expect more than one match on a line anyway);
sed 's/^91\.//' input.txt |
grep -x '.\{10\}' |
grep "^[6-9]" > output.txt
You might also be able to get rid of at least one useless grep but at this point, I would switch to Awk:
awk '{ sub(/^91\./, "") } /^[6-9].{9}$/' input.txt >output.txt
The sub() does what your sed replacement did; the final condition says to print lines which match the regex.
The same can conveniently, but less readably, be written in sed:
sed -n 's/^91\.([6-9][0-9]\{9\}\)$/\1/p' input.txt >output.txt
assuming your sed dialect supports BRE regex with repetitions like [0-9]\{9\}.
I have a log and I want to print all the lines from the log between two dates 02/04/2015:14:23:00 and 02/04/2015:14:23:59
This case is very simple - use grep and match 02/04/2015:14:23::
grep '02/04/2015:14:23:' log.txt
General/universal case is more complicated. You have to find first and last line, and then print lines.
To find first and last line, use something like this (dates only for example):
FIRST=`grep -n '02/04/2015:14:30:12' log.txt | head -n 1 | cut -f 1 -d:`
LAST=`grep -n '02/04/2015:14:43:43' log.txt | tail -n 1 | cut -f 1 -d:`
Command greps all lines matching some pattern, than selects first/last matching line, and cuts the line number from it.
This can be used with tail and head to select matching lines:
tail -n +$FIRST log.txt | head -n $(($LAST-$FIRST+1))
Following script summarize the operations:
#!/bin/bash
START_PATTERN=$1
END_PATTERN=$2
FILE=$3
FIRST=`grep -n "$START_PATTERN" $FILE | head -n 1 | cut -f 1 -d:`
LAST=`grep -n "$END_PATTERN" $FILE | tail -n 1 | cut -f 1 -d:`
tail -n +$FIRST $FILE | head -n $(($LAST-$FIRST+1))
Another approach with a sed one-liner: sed -n '/start/,/end/p' log.txt
$ cat /tmp/log.txt
before
before
before
a log line containing 02/04/2015:14:23:00 and some other stuff
between
between
a log line containing 02/04/2015:14:23:59 and some other stuff
after
after
$ sed -n '/02\/04\/2015:14:23:00/,/02\/04\/2015:14:23:59/p' /tmp/log.txt
a log line containing 02/04/2015:14:23:00 and some other stuff
between
between
a log line containing 02/04/2015:14:23:59 and some other stuff
Please note it will not work as expected if start and end tokens are in the same line.
I have a jar file, i need to execute the files in it in Linux.
So I need to get the result of the unzip -l command line by line.
I have managed to extract the files names with this command :
unzip -l package.jar | awk '{print $NF}' | grep com/tests/[A-Za-Z] | cut -d "/" -f3 ;
But i can't figure out how to obtain the file names one after another to execute them.
How can i do it please ?
Thanks a lot.
If all you need the first row in a column, add a pipe and get the first line using head -1
So your one liner will look like :
unzip -l package.jar | awk '{print $NF}' | grep com/tests/[A-Za-Z] | cut -d "/" -f3 |head -1;
That will give you first line
now, club head and tail to get second line.
unzip -l package.jar | awk '{print $NF}' | grep com/tests/[A-Za-Z] | cut -d "/" -f3 |head -2 | tail -1;
to get second line.
But from scripting piont of view this is not a good approach. What you need is a loop as below:
for class in `unzip -l el-api.jar | awk '{print $NF}' | grep javax/el/[A-Za-Z] | cut -d "/" -f3`; do echo $class; done;
you can replace echo $class with whatever command you wish - and use $class to get the current class name.
HTH
Here is my attempt, which also take into account Daddou's request to remove the .class extension:
unzip -l package.jar | \
awk -F'/' '/com\/tests\/[A-Za-z]/ {sub(/\.class/, "", $NF); print $NF}' | \
while read baseName
do
echo " $baseName"
done
Notes:
The awk command also handles the tasks of grep and cut
The awk command also handles the removal of the .class extension
The result of the awk command is piped into the while read... command
baseName represents the name of the class file, with the .class extension removed
Now, you can do something with that $baseName