Tag Info

Hot answers tagged

22

less has very powerful pattern matching. From the man page: &pattern Display only lines which match the pattern; lines which do not match the pattern are not displayed. If pattern is empty (if you type & immediately followed by ENTER), any filtering is turned off, and all lines are displayed. While filtering is in ...


10

This behavior is totally normal, it's due to how bash manages pipe usage. pipe is implemented by bash using the pipe syscall. After that call, bash forks and replaces the standard input (file descriptor 0) with the input from the right process (grep). The main bash process creates another fork and passes the output descriptor of the fifo in place of the ...


9

With sed you can use a range and quit input at a single completion: sed '/^182$/p;//,/^ABC$/!d;/^ABC$/!d;q' Similarly w/ GNU grep you can split the input between two greps: { grep -n -m1 '^182$'; grep -n -m1 '^ABC$'; } <<\IN 123 XXY 214 ABC 182 558 ABC 856 ABC IN ... which prints... 5:182 2:ABC ... to show that the first grep found a ^182$ ...


6

awk -F":" '{OFS=":"; print $1,$2,$3,$4-5,$5+5}' filename Output: 1314:Battery:1.90:45:35


6

The pipe does not behave like ;. It starts both the processes together. Which is why the grep command showed up too. So when you gave ps aux | grep myprocess , the ps aux included the grep myprocess, so the grep included that in its output. To check this, I gave two dd commands on my test server like this: [sreeraj@server ~]$ dd if=/dev/urandom ...


6

When I'm only interested in presence of a process, I use pgrep which doesn't show this behaviour, e.g.: $ pgrep myprocess 1900 In other cases (when i'm interested in more info), I usually add a '| grep -v grep' to discard grep lines, e.g.: $ ps -ef | grep myprocess| grep -v grep hth.


5

you are overquoting... grep -E '\<[0-9]{4}-[0-9]{2}-[0-9]{2}\>'


5

Probably awk would be fastest shell tool here. You could try: awk "/$regex1/ { ++r1 } /$regex2/ { ++r2 }"' END { print "regex1:",r1 "\nregex2:",r2 }' <infile Of course if you need to use perl regular expressions like your question, then really perl is the only answer. However, awk does use extended expressions (like grep -E) as opposed to ...


5

You could use perl: perl -wne 'print if (/term1/ && /term2/) || (/term1/ && (/term3/ xor /term4/))'


5

With awk, as with perl, you'll have to wrap terms in //, but it can be done: awk '(/term1/ && /term2/) || (/term1/ && xor(/term3/, /term4/))'


5

xargs grep -i -- foo /dev/null < files.txt assuming files are blank or newline delimited (where quotes or backslashes can be used to escape those separators). With GNU xargs you can specify the delimiter with -d (which then disables the quoting handling though). (unset IFS; set -f; grep -i -- foo $(cat files.txt)) assuming files are space, tab or ...


4

From the comments, I understand that you are looking to extract lines whose 7th column is either + or -. The input file is tab-separated. To do that, while saving the + lines to the file called plus and the minus lines to the file called minus, the most natural tool is probably awk: awk -F'\t' '$7=="+"{print >"plus"} $7=="-"{print>"minus"}' file ...


4

To read a list of file names from stdin you can use xargs. E.g., cat files.txt | xargs -d'\n' grep -i -- 'foo' By default, xargs reads items from the standard input, delimited by blanks. The -d'\n' tells it to use newline as the argument delimiter, so it can handle file names containing blanks. (As St├ęphane Chazelas points out, that's a GNU extension). ...


4

This answer is more suitable for a comment but it would be too long so I'm posting it as an answer. grep behavior piqued my interest and I think that OP is on the right track, I also found that newer versions of grep behave differently than older ones. In older versions if you didn't pass a parameter when using -r it only searched for a pattern in standard ...


4

Note that you don't have to read the file beforehand, sed has the r command that can read a file: $ printf -v var "%s\n" "s1random stuff" "s2 more random stuff" "s1 final random stuff" $ echo "$var" s1random stuff s2 more random stuff s1 final random stuff $ sed '/^s2/r file.txt' <<< "$var" s1random stuff s2 more random stuff line 1 line 2 s1 ...


4

With GNU grep if built with PCRE support and assuming $string doesn't contain \E, you can do: grep -P "^\Q$string"


4

Quotes (either single or double) around an argument inhibit glob expansion. Your first example passes a Regular Expression as an argument to grep. Your second example contains a glob pattern which the shell itself expands, passing filenames that fit that pattern as arguments to grep.


3

The fastest solution I can think is flex. Following is an untested skeleton: %{ int count[1000]; %} %% regex0 {count[0]++; } regex1 {count[1]++; } ... .|\n {} %% int main(){ yylex(); // printf the counts; } flex makes a pretty good job in optimizing the automata and generates fast C code. You have to recompile it if regexs change... EDIT: ...


3

With perl: perl -i -F: -lape '$F[3]-=5;$F[4]+=5;$_=join ":",@F' the-file With sh (assuming those numbers are always decimal integers without leading zeros): IFS=: read -r a b c d e < the-file && printf '%s\n' "$a:$b:$c:$((d-5)):$((e+5))" > the-file With recent versions of GNU awk: gawk -i inplace -F: -vOFS=: '{$4-=5;$5+=5}1' the-file


3

ps xao pid,ppid,s | grep '^ *[5-8]' If the PID is five digits, you don't have a space at the beginning of the line, hence the ' *' part after grep. '^'^ only searches at the beginning (thereby not selecting PPID is starting with 5,6,7,80 and. '[5-8]' handles the range of numbers you wanted (could also do '[5678]')


3

You're correct, that's not how it works. The shell doesn't wait for the first process in a pipeline to exit before starting the next. It starts them all. As such, the ps may see the grep already running.


3

You could use the read command (bash builtin) to force characters to be read one by one : netcat localhost 9090 | ( cnt=0 line= while read -N 1 c; do line="$line$c" if [ "$c" = "{" ]; then cnt=$((cnt+1)) elif [ "$c" = "}" ]; then cnt=$((cnt-1)) if [ $cnt -eq 0 ]; then ...


3

Add space after [ (it is a command) Use -n to test if length of string is nonzero, or -z to test if it is zero Put double quotes around variables So: read finding if [ -z "$finding" ]; then echo "You didn't enter anything" else grep "$finding" information.txt if [ ! "$?" -eq 0 ]; then echo "No such information in database." fi fi ...


3

You seem to be grepping the list of filenames, not the files themselves. <(cat files.txt) just lists the files. Try <(cat $(cat files.txt)) to actually concatenate them and search them as a single stream, or grep -i 'foo' $(cat files.txt) to give grep all the files. However, if there are too many files on the list, you may have problems with number ...


3

awk might be more up to the task awk '{sep=$3 in a?",":"";b[$3]++; a[$3]=a[$3]sep$1}; END{for (k in a) print k, b[k], a[k]}' file


3

The pattern argument to grep is in fact a newline-separated list of patterns. Thus grep $'\r\n' searches either a CR or the empty pattern (which matches every line). This is the same as grep $'\n' which searches the empty pattern or the empty pattern. To search for a CRLF sequence, search for a CR at the end of the line. grep -c $'\r$' file


3

First, you need to find out whether the messages you want are getting sent to stdout or stderr. In your first example, you've got stderr getting redirected to stdout - that's the "2>&1" part. You also have "/dev/null" on the command line, which doesn't entirely make sense. Why does "/dev/null" appear on command line? Second, you need to decide what ...


3

Compare also: echo '.*[s]' file with echo .*[s] file This outputs the arguments as seen by the command. In your first example you pass your grep command exactly two arguments: the pattern and the file. In your second example your shell will handle the first argument and replace it with all the files starting with a dot and ending in "s". Therefore ...


2

I think the issue is the absence of newlines in the netcat output. I can see two workarounds: Insert a newline every x seconds (with unfortunate consequences if the newline is inserted in the middle of source): ( while sleep 1; do echo; done & netcat ... ) | grep source Use awk with an RS other than newline: netcat ... | awk -v RS='}' -v ORS='}' ...


2

As @steeldriver mentionned, the problem is likely to be caused by a different line ending style than what grep is expecting. To check the line endings You can use hexdump to check exactly how your line endings are formatted. I suggest you use my favorite format : hexdump -e '"%08_ad (0x%08_ax) "8/1 "%02x "" "8/1 "%02x "' -e '" "8/1 "%_p""|"8/1 ...



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