grep -1 freezes, but it should report the invalid flag [closed] - linux

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 6 years ago.
Improve this question
grep -1 gives an error, as it should. But
$ touch foo
$ grep -1 foo
freezes. It doesn't report the invalid flag. Why is this happening? Is it a bug?
I've tested it on Mac (El Capitan) and Ubuntu (14.04).

For modern GNU and MacOS BSD implementations, grep -1 foo is reading from stdin, filtering files for lines containing foo -- which was interpreted as a pattern, not a filename. This differs from grep foo by having the amount of context to print surrounding each match set to a single line, thus being equivalent to grep -C1 foo.
Reading the source to GNU grep, it explicitly allows numbers as short options:
static char const short_options[] =
"0123456789A:B:C:D:EFGHIPTUVX:abcd:e:f:hiLlm:noqRrsuvwxyZz";
These are stored in DEFAULT_CONTEXT, determining how many lines of context to print surrounding each match, unless overridden with the more explicit -A or -B (indicating how many lines to print after of before a match). This is the same value set with -C.
Thus, in the GNU implementation and in BSD implementations extended to behave similarly to it,
grep -C3 foo
...and...
grep -3 foo
...behave identically, printing three lines of context surrounding each match.
To demonstrate this behavior:
$ printf '%s\n' 3 2 1 foo 1 2 3 | grep -0 foo
foo
$ printf '%s\n' 3 2 1 foo 1 2 3 | grep -1 foo
1
foo
1
$ printf '%s\n' 3 2 1 foo 1 2 3 | grep -2 foo
2
1
foo
2
1

Related

Variable quoting difference between bash 4.3.43 and 4.4.19 [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 4 years ago.
Improve this question
Out of curiosity I wonder which change in bash (or head?) made this the following behaviour change,
In 4.4.19 we have the following behaviour,
# Assign "foo <new line> bar" to variabe 'var'
$ > var="foo
bar"
# Echo with and without quotes,
$ > echo "${var}"
foo
bar
$ > echo ${var}
foo bar
# Read all lines (1) except the last,
$ > head -1 <<< ${var}
foo
$ > head -1 <<< "${var}"
foo
Doing the exact same thing in bash 4.2.46 and 4.3.43 results in different output when reading the variable with head.
# Assign "foo <new line> bar" to variabe 'var'
$ > var="foo
bar"
# Echo with and without quotes,
$ > echo "${var}"
foo
bar
$ > echo ${var}
foo bar
$ > head -1 <<< ${var}
foo bar
$ > head -1 <<< "${var}"
foo
So it seems to me (with 4.4.19) that no matter if you quote the variable or not, head's input will be both lines. And with versions 4.2.46 and 4.3.43 the input actually differs depending on if you quote the variable or not.
The earlier behaviour makes sense to me, where you would have to quote the variable if you want the new line. I'm genuinely interested in this behaviour change and the reasoning behind it. I tried looking through the bash-changelog, but nothing obvious stood out to me that would lead to this change (although I have some very vague feeling that I've stumbled on this before).
Thanks in advance!
The behavior in bash 4.3 is a bug which is fixed in 4.4. See the original bug report and
Chet's reply (2015/09).
And the most recent posts to bash mailing list regarding this: the question and Chet's reply (2017/11).

How to color ls - l command's columns [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 9 years ago.
Improve this question
I wonder if possible to have ls -l colored. I'm not talking about --color, of course.
I found an useful alias for display octal permission in an ls -l command, now, it's possible to color it? In the same way, is possible when I do ls -l, display only permissions in red or something?
I don't know how to use color code, but grep has --color option
If the first line of ls -l is not important to you, you can consider using grep
ls -l | grep --color=always '[d-][r-][w-][x-][r-][w-][x-][r-][w-][x-]'
or in shorter form:
ls -l | grep --color=always '[d-]\([r-][w-][x-]\)\{3\}'
You can use several utilities to do it, like piping the output of ls (OPTIONS...) to supercat (after defiining the rules). Or to highlight (after defining the rules).
Or use awk/sed to pretty print based on regexes. E.g. with gensub in awk, you can insert ANSI color codes to the output...
The first thing that came into my mind is that you can use --color=auto for this:
ls -l --color=auto
And it can be handy to create an alias:
alias lls='ls -l --color=auto'
However I see you don't want that. For that we have to create a more complex function that use the echo -e "colours...":
print_line () {
red='\e[0;31m'
endColor='\e[0m'
first=${1%% *}
rest=${1#* }
echo -e "${red}$first${endColor} $rest"
}
lls () {
IFS=$'\n'; while read line;
do
# echo "$line"
print_line $line
done <<< "$(find $1 -maxdepth 1 -printf '%M %p\n')"
}
If you store them in ~/.bashrc and source it (. ~/.bashrc) then whenever you do lls /some/path it will execute these functions.
If you're asking if there is an option to specify custom column-specific colors in ls, I don't think so. But you can do something like.
> red() { red='\e[0;31m'; echo -ne "${red}$1 "; tput sgr0; echo "${*:2}"; }
> while read -r line; do red $line; done < <(ls -l)

Meaning of command ls -lt | wc -l [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 9 years ago.
Improve this question
My friend just passed me this command to count the number of files in a directory:
$ ls -lt | wc -l
Can someone please help me flush out the meaning of this command? I know that ls is to list all the files. But what does -lt mean?
Also, I get a different count if I use ls | wc -l with no -lt option. Why is that the case?
You'll want to get familiar with the "man (manual) pages":
$ man ls
In this case you'll see:
-l (The lowercase letter ``ell''.) List in long format. (See below.) If
the output is to a terminal, a total sum for all the file sizes is
output on a line before the long listing.
-t Sort by time modified (most recently modified first) before sorting the
operands by lexicographical order.
Another way you can see the effect of the options is to run ls without piping to the wc command. Compare
$ ls
with
$ ls -l
and
$ ls -lt

linux/ unix command for checking specific logs [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 9 years ago.
Improve this question
how can I extract a log based on specific time frame? Let's say issue started between 4pm to 5pm, how can I get that specific log between those times? I can use less or cat or grep but it would not give me the details of the error, sample command:
grep "2013-08-26 16:00:00" sample.log
what is the more precise Linux/ Unix command that can do the trick?
For viewing ERROR log messages between 16:00:00 and 17:00:00 use:
grep -nP '2013-08-15 16:.+ERROR' sample.log | less
If you have multiline messages in log you can use -A n and -B n params to add for each output string n lines after or before:
3 lines before and after each line:
grep -A 3 -B 3 -nP '2013-08-15 16:.+ERROR' sample.log | less
Shorthand for the same:
grep -3 -nP '2013-08-15 16:.+ERROR' sample.log | less
If you know that issue happened between 4 and 5 pm, you can use this:
grep "2013-08-26 16:" sample.log | less
If you need some lines around that issue, add option -N to grep (context of N lines), something like that:
grep -3 "2013-08-26 16:" sample.log | less
If you know that your event contained some specific word, you can filter it more using one more grep:
grep -3 "2013-08-26 16:" sample.log | grep somethingelse

Is \d not supported by grep's basic expressions? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 1 year ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Improve this question
This does not generate any output. How come?
$ echo 'this 1 2 3' | grep '\d\+'
But these do:
$ echo 'this 1 2 3' | grep '\s\+'
this 1 2 3
$ echo 'this 1 2 3' | grep '\w\+'
this 1 2 3
As specified in POSIX, grep uses basic regular expressions, but \d is part of a Perl-compatible regular expression (PCRE).
If you are using GNU grep, you can use the -P option, to allow use of PCRE regular expressions. Otherwise you can use the POSIX-specified [[:digit:]] character class in place of \d.
echo 1 | grep -P '\d'
# output: 1
echo 1 | grep '[[:digit:]]'
# output: 1
Try this $ echo 'this 1 2 3' | grep '[0-9]\+'

Resources