Hot answers tagged

18

The wc command is counting the words in the output from grep, which includes "for": > grep shell test.txt for shell_A shell_B shell_C So there really are 4 words. If you only want to count the number of lines that contain a particular word in a file, you can use the -c option of grep, e.g., grep -c shell test.txt Neither of those actually count ...


16

The command 'grep' is outputting the entire lines that "shell" appear on. Not just the word "shell." As can be seen below: grep shell test.txt for shell_A shell_B shell_C I would recomend using the option -o, --only-matching So: grep -o "shell" test.txt | wc -w


10

tops default output is intended for terminal. As such is uses various control codes (invisible when viewed in a terminal). Those include various ways to move around the screen. Style output etc. To get a more friendly output for text files / editing or what ever use the batch mode. top -b ...


9

The right tool for this job is column. You can specify column separator with -o (on OS X it's -s) , e.g.: column -t -o ' ' file gives TLRUIDA CBdms Status DP 6/1/1 DC 6/1/5 0 Y TLRUIDA CBdms Status DP 6/2/1 DC 6/2/5 0 Y TLRUIDA CBdms Status DP 6/3/1 DC 6/3/5 0 Y TLRUIDA CBdms Status DP 6/4/1 ...


6

--color adds escape sequences for the color. You can see this if you redirect the output (of ls --color) to a file. This is what it looks like: drwxr-xr-x 6 root root 4.0K Jan 9 08:23 ^[[01;34m.cabal^[[0m/ To account for this, try this instead: ls -lhAF1 --color | grep -E '^d.*[0-9]{2}:[0-9]{2} .*\.'


6

Parsing ls is often a bad idea. Often, but not always. Here's another suggestion for you, which collects the required directories together before passing the set to ls. find .* -maxdepth 0 -type d \( -name '.[^.]' -o -name '.??*' \) -exec ls -ld --color=always {} + It's been pointed out that the original code actually limits the list of directories to ...


6

Use a JSON aware tool. Perl has the JSON library: #!/usr/bin/perl use warnings; use strict; use JSON; my $json = '[{"product":"Apple","id":"2134"},{"product":"Mango","id":"4567"}]'; print 'Enter product: '; chomp( my $product = <> ); print 'Your product id is: ', (grep $_->{product} eq 'Apple', @{ from_json($json) })[0]{id}, "\n";


5

You can start a sub shell and use $0 variable to do this. bash -c 'echo "$0: $(grep -c $0 example.txt)"' 'Thenis' > example.lst


5

It's an interesting behavior you've noticed there. It's wrong to classify it as a "bug" because POSIX doesn't specify a -o option for grep. You may not like how it behaves, and I'll agree that it's annoying that BSD and GNU grep differ, but this behavior is not actually in conflict with what the BSD manual pages say. If you still say it's a bug, well, you ...


5

That result you're getting is because . matches any single character From manpage >REGULAR EXPRESSIONS:    The fundamental building blocks are the regular expressions that match a single character. Most characters, including all letters and digits, are regular expressions that match themselves. Any meta-character with ...


5

If the input is processed line by line, then processing needs to go like this: if the current line is foo.bar, store it, forgetting any previous foo.bar line that wasn't enabled for output; if the current line is relevant=yes, this enables the latest foo.bar for output. This kind of reasoning is a job for awk. (It can also be done in sed if you like ...


5

since you can have the word "shell" multiple times on a line I would start with breaking up the text in single words per line and then do the grep < test.txt tr -s "[[:blank:]]" "\n" | grep "shell" | wc -w you can also use wc -l, or do away with wc and use grep -c "shell" And you can even remove the need for tr on the file that you have and use: ...


4

Since grep -c prints only the number, we need to prefix with the given pattern. This can be accomplished by using the shell builtin printf to print the pattern without a following newline. Then we let grep print the count (on the same line). Using parenthesis to place both statements in a sub-shell allows all of the output to be redirected only once. I ...


4

Provided there are fewer than 999,999 lines: grep -A 999999 '19/Jan/2016:22:' access_log But this would be a better solution as it doesn't restrict the number of lines after the match: sed -n '/19\/Jan\/2016:22:/,$p' access_log


4

Use the -o option of grep to select only the desired portion, in your case use pattern on line .* to select the portion starting from on line till the end of the line(s): % grep -o 'on line .*' temp.txt >new.txt % cat new.txt on line jhkjhvjdbvjvbvbdjkvn on line fdgdgdgdd on line safffasffaf on line adaddsd


4

grep is the command that implements the g/<RE>/p command in ed/ex (hence its name), that is, it prints the lines that match a given regular expression (regex or regexp for short). Here, '^[^:]\+::' is the regular expression (quoted so the shell doesn't treat some of those characters specially). More precisely (as there are several implementations of ...


4

Try grep: grep -iv dog inputfile -i to ignore case and -v to invert the matches. If you want to use sed you can do: sed '/[dD][oO][gG]/d' inputfile In sed, there is also the I flag, which should make the match case insensitive, but as far as I remember this does not work in all flavors of sed. For me, this works: sed '/dog/Id' inputfile but it ...


3

From man grep -F, --fixed-strings Interpret PATTERN as a list of fixed strings, separated by newlines, any of which is to be matched. (-F is specified by POSIX.) So it's just checking for the presence of = as a literal string in $line


3

In this particular case, it will be enough to just change all occurrences of two or more spaces to a tab: sed 's/ */\t/g' file For a more general solution, you can make sure each column is printed with the right width using printf. You can do this directly in the shell: $ while read line; do printf '%-8s%-6s%-7s%-3s%-8s%-3s%-7s%-2s%-2s\n' $line; ...


3

Use awk. awk uses associative arrays; you can build an array with the numbers from select.dat as the keys and don't bother to assign any values. Then you can use the simple check "___ in <arrayname>" as the filter to determine what to print. NR means "record number" and FNR means "file record number". The test FNR == NR essentially means, "Am I ...


3

Check your single quotes. Single quotes don't magically nest. alias sll 'ls -l \!* | grep -oE '\''[^ ]+$'\'' | xargs ls -ld --' That's still flawed for several reasons: Because of [^ ], that won't work for file or link target names that contain spaces. as you're treating that list as a list of lines, that won't work with file/link target names that ...


3

You could use grep with -A. Something like: $ grep -A 13 '^\[2\]' inputfile.txt The -A specifies the number of lines you want to include after the match. But I think it would be better to use sed in this case: $ sed -n '/^\[2\]/,/^$/p' inputfile.txt This will print everything between [2] and an empty line. The same using awk: $ awk -v RS='' -v ...


3

Here's one way with sed: sed '/foo\.bar/h;/relevant=yes/!d;x;/foo\.bar/!d' infile Lines matching foobar are copied to hold space. All lines, except those matching relevant=yes are deleted. Exchange hold space with pattern space (this only happens when lines match relevant=yes) and delete if it doesn't match foobar.


3

The output of tr is buffered. You can use stdbuf -o0 with tr to make it's STDOUT unbuffered: cdrecord -v ... | stdbuf -o0 tr '\r' '\n' | grep -i written


3

grep -rc 'Author' $1 | sort -t : -k 2,2n is good if you want the number of lines containing the keyword, regardless how many times it repeats on any given line. If you want the actual word count, you should use this echo $1:$(grep -o 'Author' $1|wc -l) | sort -t : -k 2,2n -o option for grep is most probably available on the gnu version of grep. If you ...


3

To sort from highest to lowest: grep -rc 'Author' $1 | sort -r -t ':' -k2,2n -r sorts in reverse order, that is, from highest to lowest. -t introduces the separator. -k introduces which fields to sort by. The fields are separated by the separator defined by -t. This syntax means to sort by all of the fields between 2 and 2 (so just the second field). The ...


2

echo $i instead of trying to open it as a file: for i in $(cat aaa) do A= $(echo $1 | awk -F '_' '{print $1}') B= $(echo $i | awk -F '_' '{print $2}') grep $B bigfile.txt > $A done However, if you are interested, you could replace this for-loop entirely with an awk one-liner: awk -F '_' '{system("grep "$2" bigfile.txt > "$1)}' aaa


2

grep supports regular expressions. Example: curl -i -X PUT -T test1.txt "http request"| grep -E "(HTTP|Exception)"


2

I've made a script to grep recursively for a pattern, and then I can select one of the matches so vim will open that file in that line. I call it vgrep (vim grep, although it uses also awk in it). The following is its code: #!/bin/bash my_grep() { grep -Rn -I --color=auto --exclude-dir={.svn,.git} --exclude={tags,cscope.out} "$@" . 2>/dev/null } ...


2

Your function was trying to evaluate $returnString on the left-hand side during the assignment; instead, you want: eGrepUsernames(){ returnString=""; for username in "${usernames[@]}" do returnString="$returnString -e $username" # this line changed done printf '%s ' $returnString; ## so did this one }



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