get only the value...not what your grepping for - unix

pdftk file.pdf dump_data output | grep NumberOfPages:
gives me:
NumberOfPages: 5
I don't want it to output NumberOfPages. I want to get in this case just 5. Is there a flag I can say in grep to get just that? I did a man grep and nothing seemed to do the trick.

I think grep doesn't know about how to parse strings in different formats. But other utilities like awk will help you:
pdftk file.pdf dump_data output | grep NumberOfPages: | awk '{print $2}'

pdftk file.pdf dump_data output | grep NumberOfPages: | sed 's\NumberOfPages:\\'

Yes, in GNU Grep you can use the -o operator to get "only" the matching portion of your expression. So something like;
pdftk file.pdf dump_data output | grep -o ' .*'
Could work for you. As other answers have pointed out, if you want only the number you'd be better off using something in addition to grep.
For example:
$ echo 'NumberOfPages: 5' | grep -o ' .*'
5
Notice the space before the 5 being included.

Related

grep multiple files get count of unique cut

I think I'm close on this, and saw similar questions but couldn't get it to work as I want. So, I have several log files and I would like to count the occurrences of several different service calls by date.
First I tried the below, the cut is just to get the first element (date) and 11th element (name of service call), which is specific to my log file:
grep -E "invoking webservice" *.log* | cut -d ' ' -f1 -f11 | sort | uniq -c
But this returned something that looks like:
5 log_1.log:2017-12-05 getLegs()
10 log_1.log:2017-12-05 getArms()
7 log_2.log:2017-12-05 getLegs()
13 log_2.log:2017-12-04 getLegs()
What I really want is:
12 2017-12-05 getLegs()
10 2017-12-05 getArms()
13 2017-12-04 getLegs()
I've seen examples where they cat * first, but looks like the same problem.
cat * | grep -E "invoking webservice" *.log* | cut -d ' ' -f1 -f11 | sort | uniq -c
What am I doing wrong? As always, thanks a lot!
Your issue seems to be that grep prefixes the matched lines with the filenames. (grep has this behavior when multiple filenames are specified, to disambiguate the results.) You can pass the -h to grep to not print the filenames:
grep -h "invoking webservice" *.log | cut -d ' ' -f1 -f11 | sort | uniq -c
Note that I dropped the -E flag, because it is used to enable extended regex support, and your example doesn't need it.
Alternatively, you could use cat to dump the content of files to standard output, and pipe that to grep. That would work, because it removes the need for filename parameters for grep:
cat *.log | grep "invoking webservice" | cut -d ' ' -f1 -f11 | sort | uniq -c

What is the easiest way for grepping the 'man grep' for flags

I do use grep a lot, but I would love to improve a bit.
Regarding the question. I wanted to narrow the man entry to find the explanation of what the -v in grep -v 'pattern' filename stood for, mainly this:
-v, --invert-match
Selected lines are those not matching any of the specified patterns.
Thus, to find the next five lines after the line which contains -v I tried:
man grep | grep -A 5 -v
and
man grep | grep -A 5 '-v'
but they return:
usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
[-e pattern] [-f file] [--binary-files=value] [--color=when]
[--context[=num]] [--directories=action] [--label] [--line-buffered]
[--null] [pattern] [file ...]
This confuses me since:
man grep | grep -A 5 'Selected'
and
man grep | grep -A 5 Selected
do work.
What is wrong in my approach? Is there any easier way to achieve what I need?
One approach is to parse the Info documents for the command directly. If you run info grep (or other command) you will often find much more detailed and better-structured documentation, which will let you pin-point just the section you need.
Here's a function that will print out the relevant Info section for an option/variable/etc:
info_search() {
info --subnodes "$1" -o - 2>&- \
| awk -v RS='' "/(^|\n)(‘|'|\`)$2((,|\[| ).*)?(’|')\n/"
}
This should work on Linux/macOS/BSD. Output is like:
$ info_search grep -v
‘-v’
‘--invert-match’
Invert the sense of matching, to select non-matching lines. (‘-v’
is specified by POSIX.)
$ info_search gawk RS
'RS == "\n"'
Records are separated by the newline character ('\n'). In effect,
every line in the data file is a separate record, including blank
...
$ info_search bash -i
`-i'
Force the shell to run interactively. Interactive shells are
...

Splitting unix output

I'm trying to extract an address from a file.
grep keyword /path/to/file
is how I'm finding the line of code I want. The output is something like
var=http://address
Is there a way I can get only the part directly after the = i.e. http://address , considering the keyword I'm greping for is both in the var and http://address parts
grep keyword /path/to/file | cut -d= -f2-
Just pipe to cut:
grep keyword /path/to/file | cut -d '=' -f 2
You can avoid the needless pipes:
awk -F= '/keyword/{print $2}' /path/to/file

How to get a list of file names in different lines

I want to get a list of all the files in a directory, like with ls, so that each filename will be on a seperate line, without the extra details supplied by ls -l. I looked at ls --help and didn't find a solution. I tried doing
ls -l | cut --fields=9 -d" "
but ls doesn't use a fixed number of spaces between columns. Any idea on how to do this, preferably in one line?
ls -1
That is a number, not small L.
ls -1. From the help:
-1 list one file per line
Works on cygwin and FreeBSD, so it's probably not too GNU-specific.
solution without pipe-ing :-)
ls --format single-column
Note that the long options are only supported on the GNU coreutils where BSD ls only supports the short arguments -1
Perhaps:
ls | awk '{print $NF}'
ls | cat
...
or possibly, ls -1
Use sed command to list single columns
ls -l | sed 's/\(^[^0-9].\*[0-9]\*:[0-9]\*\) \(.*\)/\2/'
Try this:
$ ls | xargs -n num
Here num is number of columns you want to list in.
first you can use this. it will display the one file per line.
ls -l | sed 's/(.* )(.*)$/\2/'
or else you can use thus
find . -maxdepth 1 | sed 's/.///'
both the things are the same.
This is also working: echo -e "\n$(ls)"
This will also do
ls -l | awk '{print $NF}'

zcat to grep with file name

ls -ltr|grep 'Mar 4'| awk '{print $9 }'|xargs zcat -fq |grep 12345
I'm now using this command to list the records that contain my numeric string how can i alos get this command to print the name of the file the strings were found in?
thanks
Use zgrep
BTW. what you're trying to do can be done with find
find -newermt 'Mar 4' -and ! -newermt 'Mar 5' -exec zgrep -l '12345' {} \;
If you use zgrep instead of zcat+grep (which does the same), you do it like this option like this:
ls -ltr | grep 'Mar 4' | awk '{print $9}' | xargs zgrep 12345
Pass the -t option to xargs, causing it to print the command it is running (the zcat command, including the filename) before running it. The command is printed to stderr, so it will not interfere with your pipe.

Resources