Tag Info

Hot answers tagged

28

Your suspicion is correct; the exit status of the last command of the script will be passed to the calling environment. So the answer is that this script will return an exit status 0 if grep matched someting in the data, exist status 1 if there was no match, and exit status 2 if some error occurred.


24

The point of grepping output that is thrown away is that the writer only wants the return status of grep. He/She only wants to know whether a pattern matched or not. In your case, the last grep checks if the earlier command's output contains any lines start with 200. In modern POSIX system, you can do it all with grep -q without redirecting to /dev/null: ...


16

id also accepts paramters, so you don't have to grep for it (-g to print only the group, and -n to print names instead of ids): $ id -gn usera groupa To save that into a variable use that: groupname=$(id -gn usera)


14

Characters of code 0 to 31 in ASCII are control characters. When sent to a terminal, they're used to do special things. For instance, \a (BEL, 0x7) rings the terminal's bell. \b (BS, 0x8) moves the cursor backward. \n (LF, 0xa) moves the cursor one row down, \t (TAB 0x9) moves the cursor to the next tabulation... \r (CR, 0xd) moves the cursor to the first ...


10

You still use grep... with the -v option, which tells grep to print only those lines which do not match the pattern: grep -v pattern myfile


9

GNU grep's -w will only consider the 26+26+10+1 (ASCII letters, digits and underscore) as word constituents. You can't change that, even by using a different locale (even in a locale where é is considered a letter, Stéphane would still be St and phane separated by the non-word é). You can however implement that logic by hand: grep -E ...


8

* in a regex is not like a filename glob. It means 0 or more of the previous character/pattern. So your examples would be looking for a A then 0 or more B then -DEF . in regex means "any character" so you could fix your pattern by using grep 'AB.*DEF'


6

The error message you received probably indicates that no file matched the name pattern .swp$. A generally safer way to do what you wrote (because it will handle any file name): find . -name '*.swp' -print0 | xargs -0 rm -i --


6

Try this: pcregrep -M '\bThis\s+is\b' <<EOT This is an example file. EOT


6

The GNU grep can do it grep -z 'is\san\sexample\sfile.' file To fulfill some points which arise in comments there are some modifications to script: grep -oz '^[^\n]*\bis\s*an\s*example\s*file\.[^\n]*' file Regarding huge files I have no imagination of memory limitation but in the case of problem you are free to use sed sed '/\bis\b/{ :1 ...


5

Your grep doesn't support the -A flag, so you can't use that. But you should be able to get the same result with awk. awk -v dt=$(date +%m/%d) '$0~dt{counter=5}counter>=0{print;counter--}' file.txt This sets a counter to 5 when a match is found, and prints and decrements the counter while it's not negative.


5

Or a variation with find alone e.g.: find . -name "*.swp" -ok rm {} + or just without confirmation (WARNING!): find . -name "*.swp" -delete


5

\x0d is the character \r which brings the cursor to the start of the line, then \x20 is a space, so it overwrites the a with a space. If you're on a unix-y system you may want to consider just removing \r from your output/file since it's not needed if it's for text output. The \n "implies" it for *nix, but not for Windows.


5

grep is a program that searches for regular expressions. The first argument for grep is the pattern to look for. In scripts and functions $1 is a reference to the first argument passed to that script or function. The ^ prepended to the argument is a standard regular expressions modifier that matches the beginning of a line -- this way you can ensure that ...


5

I'd use Perl's paragraph mode: pactl list sink-inputs | perl -00ne 'print if s/(.*?VLC.*?\n).*/$1/ms' The -00 sets the input record separator to \n\n so a "line" is a paragraph. Then, the substitution will match everything until the first VLC and then anything until the 1st newline and save them as $1. Everything after that is removed (since we're ...


5

With ed: ed -s <<'IN' r !pactl list sink-inputs /VLC/+,$d ?Sink Input?,.p q IN It reads the command output into the text buffer, deletes everything after the first line matching VLC and then prints from the previous line matching Sink Input up to current line. With sed: pactl list sink-inputs | sed -n 'H;/Sink Input/h;/VLC/{x;p;q}' It appends ...


5

Use option -h. -h, --no-filename Suppress the prefixing of file names on output. This is the default when there is only one file (or only standard input) to search.


4

You can use awk and its string comparison operator. ls | awk '$0 < "3_20150415"' In a variable: max=3_20150414 export max ls | LC_ALL=C awk '$0 <= ENVIRON["max"] "z"' concatenating with "z" here makes sure that the comparison is a string comparison, and allows any time on that day since in the C locale, digits sort before z.


4

Different tools and versions thereof support different variants of regular expressions. The documentation of each will tell you what they support. Standards exist so that one can rely on a minimum set of features that are available across all conforming applications. For instance, all modern implementations of sed and grep implement basic regular ...


4

Some more choices. I have saved your example text in file for simplicity. grep and PCREs: $ grep -oP '(GRAPE|FRUIT)=\K.*?(?=,)' file purple yes violet affirmative To get them on the same line, just parse. For example $ grep -oP '(GRAPE|FRUIT)=\K.*?(?=,)' | paste -d" " - - – purple yes violet affirmative sed $ sed ...


4

You can just use grep as a pager: man -P 'grep NR' awk but it is way better to just search for pattern with / in less (that is probably your default pager), so: man awk and then /^ *NR This way you will find only headers (patterns at the beginning of the lines).


3

The exact equivalent would be something like: sed -n '/email2/{s/^[^=]*=\([^=]*\).*/\1/;p;}' < file But you'd probably want instead: sed -n 's/^[^=]*email2[^=]*=[[:blank:]]*//p' < file (that is match email2 only on the part before the first = and return everything on the right of the first = (skipping leading blanks), not only the part up to the ...


3

The awk equivalent of grep -w Duplications: *.info| grep -v Conditional >dups would be awk '/\<Duplications:/ && !/Conditional/ {print}' *.info > dups If a line matches the word "Duplications:" and the line does not contain "Conditional", print the line. I don't think awk offers any benefits over grep here.


3

You are correct - \w is part of PCRE - perl compatible regular expressions. It's not part of the 'standard' regex though. http://www.regular-expressions.info/posix.html Some versions of sed may support it, but I'd suggest the easiest way is to just use perl in sed mode by specifying the -p flag. (Along with the -e). (More detail in perlrun) But you don't ...


3

As far as your patterns are concerned, this would be the safest to match only intended strings: grep 'AB.\{0,1\}-DEF' file.txt Or grep -E 'AB.?-DEF' file.txt . matches any single character, ? and \{0,1\} matches the previous token zero or one time, so in total .? and .\{0,1\}will match zero or one character before -DEF. If you use AB.*-DEF or AB.*DEF, ...


3

You need two things to match the line breaks (hence multiple lines) using grep : -z option of newer GNU grep, it will cause the lines to be separated by ASCII NUL rather than line breaks (?s) is called DOTALL modifier (with grep -P), it will cause the grep to match the line breaks (LF/CR) by . (dot) So in your case the following should work: grep -aPoz ...


3

With the command you tried, echo is printing every word in the manual page on a single line. You would have had a better luck with: echo "`man awk`" | grep NR or better echo "$(man awk)" | grep NR or even better, given the fact echo is useless here: man awk | grep NR Note that most if not all man implementations detect their output is a pipe and ...


3

grep can't do this for file in one certain directory if you have more files with the same name in different directories, use find instead: find . -type f \! -path './test/main.cpp' -exec grep pattern {} \+


3

I don't think it's possible with GNU grep. You don't need pipes though. With find: find . ! -path ./test/main.cpp -type f -exec grep pattern {} + With zsh: grep pattern ./**/*~./test/main.cpp(.) (excludes hidden files, just as well to exclude the .git, .svn...).


2

With any Bourne-like shell: { cat < bigfile | grep -v to-exclude perl -e 'truncate STDOUT, tell STDOUT' } 1<> bigfile For some reason, it seems people tend to forget about that 36 year old and standard read+write redirection operator. (the cat is for GNU grep that otherwise complains if stdin and stdout point to the same file).



Only top voted, non community-wiki answers of a minimum length are eligible