New answers tagged

2

It's quite a job for sed: $ printf 'foo\nbar\n' | sed -n '$!N;/\nbar$/P;D' foo


0

yet another solution grep -B 1 "bar" test | head -n 1 it has the advantage that you don't need any additional regexp or matching test, it is therefore more efficient but this won't work for multiple match


0

Another possible solution: grep -B 1 "bar" test | sed '/bar/d'


0

You could do another grep which ignores "bar": grep -B 1 "bar" test.txt | grep -v "bar"


3

Using sed with a string You have correctly identified the problem: $reg is a string, not a file. Thus, you need to supply the string to sed as stdin. Replace: reg1=$(sed /^Domain/d $reg) with (for bash): reg1=$(sed /^Domain/d <<<"$reg") Or, for a general POSIX shell, use: reg1=$(echo "$reg" | sed /^Domain/d) Simplification: combining the ...


0

Instead of that huge script to traverse the files you can just use find: find /var/log -name *.log -exec ls {} \; Replace the path and the 'ls' in the -exec to fit your needs. As for grepping for the time you can do something like: grep "^real\t" time.txt | awk '{ print $NF }' I cannot come up with a pretty solution to formatting it though.


0

Given that foo would be used in the same context as foo and also match a full word, the easiest way is to do: grep -E -w '(foo|bar)' file


14

The word boundary has a similar effect to -w, but can be used as part of the expression. ‘\b’ Match the empty string at the edge of a word. [...] ‘\<’ Match the empty string at the beginning of word. ‘\>’ Match the empty string at the end of word. To match bar only when it's the whole word, but foo anywhere (including inside ...


0

Given your sample input, this produced your desired output: grep -Eo '["'\'']?[/[:alnum:]]+\.epl' It makes some assumptions about the characters in your filenames (letters, numbers, slashes) -- feel free to throw more characters into that set of brackets.


0

I think this will do it for you: grep -oP "(?<=['\"]|qq{)[xp/c][^\`]+" ./index.epl This says: -o Only keep the matching part. -P Use Perl style regex (we need this for the lookbehind) "..." Use double quotes since you can't escape the single within single (?<=...) Start a positive lookbehind group. This means that whatever we match much also have ...


0

The reason your sed command doesn't work is that it assumes you have a date on every line, which is not the case if some lines come from multi-line error messages. When there is nothing matching the replacement pattern, sed does no replacement and the call stack listings you saw stay in the output. To get only the dates from lines that have them in the ...


0

(Converted edit to answer) I used the plutil command to convert the plist to proper text since it was a 'binary file'. Once that was done, grep had no problem managing the file.


0

awk '/^[0-9]{2}[.][0-9]{2}[.][0-9]{4}/ {DATES[$1]++} END{ for(d in DATES) {print d} }' Unlike rock, paper, scissors: awk always beats sed. :-) Edit: here is is in action: $ cut -b-60 t 15.04.2016 13:13:30,228 INFO [wComService] [mukumukuko@sy 15.05.2016 13:14:10,886 INFO [wComService] Call 5303 from 15.06.2016 13:14:20,967 INFO ...


0

use this: awk '{print $1}' fac.log | sort | uniq


1

grep's -o option won't produce exactly the output you're looking for, but it should help you find the issue; it only outputs the matching portion of each line, and if multiple portions of a line match, it outputs each portion separately (on separate lines): /data/animals/felines.txt:cat


0

You almost have it. Step1 On GNU and Linux and perhaps other systems, the date command can be used to print out an arbitrary format for a time specification given a user-friendly time expression. For instance, I can get a string representing the time from 15 minutes in the past using this: date --date='15 minutes ago' You've pretty much done this with ...


0

I'd use: awk -v limit="$(date -d '15 minutes ago' +'[%FT%T')" ' $0 >= limit' < log-file That ignores the potential problems you may have two hours per year when the GMT offsets goes from -04:00 to -05:00 and back if daylight saving applies in your timezone. date -d is GNU specific, but you're using it already.


0

Regular expressions aren't a good choice for matching timestamps, as they don't really 'understand' numeric values. So instead, I'd suggest parsing the timestamp: #!/usr/bin/env perl use strict; use warnings; use Time::Piece; my $now = time(); my $last = $now - 15 * 60; while ( <> ) { my ( $timecode ) = m/\[([^\.]+)/; print $timecode; ...


2

ps -o user= -p PIDHERE This selects the process PIDHERE with -p, then instructs ps to format the output by printing only the column named user; the = sign means "rename the column user to (nothing)", effectively removing the header line.


2

If you enter the string literally into the command, you can escape the characters at your will. grep 'Title of Webpage which may include '\'' and "' /var/mobile/Library/Safari/History.plist grep "Title of Webpage which may include ' and \"" /var/mobile/Library/Safari/History.plist Also notice that cat isn't needed. Moreover, it's much better to use an ...


3

Problem : * is not getting expanded ; there really is no such file named * , so grep reports that. Solution : remove the last * ; it will work with -r , making grep look into all the files in that Directory.


0

awk '{ORS=""; print $0}' textfile <div id="crmpicco"> <div class="ayrshireminis">... content in here ... </div></div> Additionally, as was already pointed out, the tr utility is awesome for this. To remove newlines and tabs/spaces all at once using the tr utility, do: # cat textfile |tr -d '\n\r" "' ...


1

No, ".pdf" macthes way too much, e.g foo.pdfa and bpdf. Furthermore, even if you don't have files wrongly matching, wc without options outputs the number of lines, words and bytes in the input, so you would get two numbers more than you're interested in. If you want grep in the mix, you could do ls | grep -E "\.pdf$" | wc -l, but unless you have a lot of ...


1

You should use ls | grep ".pdf" | wc -l The -l parameter will count only the number of resulted lines, while without the -l you would get other counts as well, like newline, word, and byte count. Note that this will count filenames (and folders as well) which contain the ".pdf" chain of characters. To count only files ending with .pdf, you'd better ...


2

Your shell should be able to do the filtering: ls *.pdf | wc -l or you have to make sure you match the end of filenames: ls | grep "*\.pdf$" | wc -l (notice the dollar sign). Note: both of these will also match directories ending in ".pdf", if any. Note 2: ls should behave as if you gave it option -1 as soon as you pipe its output. Otherwise, add ...


-1

Try using the -H option to grep: -H, --with-filename Print the filename for each match. So instead of calling your script, just do: grep -H PATTERN [FILE...] Also, it's a good idea to check the man page for the tool you are using before you attempt writing a wrapper script. For common Unix tool, the simple options you want are nearly ...


1

Another option is to be more specific about what you are grepping for. For example: whois stackoverflow.com | grep -E '^[[:space:]]*(Registr(ar|ant|y)|Sponsoring).*: ' This extracts only lines that begin with optional white space before either 'Registrar', 'Registrant', 'Registry', or 'Sponsoring', followed by any number (zero or more) of any character, ...


0

I just came across the original answer here by @Mehmet while searching for something unrelated and I see that although it works, it is horribly inefficient, requiring each file to be read again for each unique word in all of the files! The second answer by @Jeff is rather convoluted despite the explanation and worst of all it suffers from the cat file | ...


2

Try this: awk '/^[*][*][*] /{ if ($0 in seen) fname=$0; else seen[$0];} fname{print>fname}' file How it works awk implicitly reads a file line by line. For each line read, we do the following: /^[*][*][*] /{ if ($0 in seen) fname=$0; else seen[$0];} For any line that begins with three stars and a space, we check to see if we have seen that line ...


2

Use the -v flag: reg=`whois stackoverflow.com | egrep -i 'Registrar|Sponsoring Registrar|Registrant' | grep -v internic`


2

according to your comment " I have a text file where where all the names are listed without the extension. I want to make a PHP script that compares the text file with the folder to see which file is missing " : for file in $(cat yourlist) ; do [ -f "${file}.png" ] || { echo "$file : listed in yourlist, but missing in the directory" } done #assumes ...


0

The program you're looking that can easily do what you want is called awk. :-) It can do programmed actions on matched RE patterns. Untested, simplified, rote, example awk program that should work with your example input and specified patterns: BEGIN { eights = 0; fives = 0; threes = 0; } /8888/ { eightln[eights] = $0; eights++; } ...


2

The first regex searches for any line containing the following: '^ - start of line, followed by [^,]* - 0 or more non-comma characters, followed by , - a comma, followed by [^0] - any single character other than a zero, followed by [^,]* - 0 or more non-comma characters, followed by ,' - a comma grep -c counts the number ...


1

grep -c '^[^,]*,[-+0-9.]*[1-9]' That should cover for numbers expressed as 12, -1, 0e+12, 01, 0.0001. But not for 0xFF or Inf or NaN for instance, so that would still be different from the more canonical: POSIXLY_CORRECT=1 awk -v n=0 -F , '$2 != 0 {n++}; END{print n}' If your input has numbers expressed in such a format. For a sed only solution, you ...


1

With grep: grep -c '^[^,]*,[^0]' <file That's only work if 2nd column is formed like integer, but not -0, +0. For more general case, see @Stéphane Chazelas's answer.


1

You can use the -c option of grep. And you can remove all chars up to the first comma and everything from the second comma on with sed: sed 's/^[^,]*,//;s/,.*//' < the_file | grep -c -E '[^0]' EDIT: This sed command does the same as your cut command so you should also be able to use your original grep command. EDIT2: If you want to use only one ...


1

A simple shell line (ksh, bash or zsh; not dash): set -- *.png; printf '%s\n' "${@%.png}" A simple function (from No Extension): ne(){ set -- *.png; printf '%s\n' "${@%.png}"; } Or a function that remove any extension given (png by default): ne(){ ext=${1:-png}; set -- *."$ext"; printf '%s\n' "${@%.${ext}}"; } Use as: ne jpg If the output is an ...


2

When you use grep with color options it produces extra escape character sequences which tell the terminal to turn color on or off, these sequences introduce a risk of not being interpreted properly and causing unexpected results. You can view these by capturing grep's output With no color send greps output to output.txt % grep -o --color=none '.\+ middle ...


1

If I knew the directory only had files with .png as an extension, I would have just run: ls | awk -F. '{print $1}' This will return the first "field" for anything where there is a filename.extension. Example: [rsingh@rule51 TESTDIR]$ ls 10.png 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png [rsingh@rule51 TESTDIR]$ ls | awk -F. '{print ...


3

It is not safe to parse ls or to pipe find[1,2] It is not safe to parse (and to pipe) the output of ls or find, mainly because it possible to find in the file names non usual characters as the newline, the tab... Here a pure shell cycle will work[cuonglm]. Even the find command not piped with the option -exec will work: find ./*.png -exec basename {} ...


1

I like joseph's answer but needed it to strip // comments also so I modified it slightly & tested on redhat # no comments alias alias nocom="sed -E '/^[[:blank:]]*(\/\/|#)/d;s/#.*//' | strings" # example cat SomeFile | nocom | less I bet there's a better way to remove blank lines than using strings but it was the quick & dirty solution I used. ...


6

You can use only BASH commands to do that (without any external tools). for file in *; do echo "${file%.*}"; done This is usefully when you're without /usr/bin and works nice for filenames like this.is.image.png and for all extensions.


9

Another very similar answer (I'm surprised this particular variant hasn't appeared yet) is: ls | sed -n 's/\.png$//p' You don't need the -1 option to ls, since ls assumes that if the standard output isn't a terminal (it's a pipe, in this case). the -n option to sed means ‘don't print the line by default’ the /p option at the end of the substitution means ...


8

I'd go for basename (assuming the GNU implementation): basename --suffix=.png -- *


4

wasn't it enough? ls -1 | sed 's/\.png//g' or in general, this ls -1 | sed 's/\.[a-z]*//g' will remove all extensions


2

Use rev: ls -1 | rev | cut -f 2- -d "." | rev rev reverses all the strings (lines); you cut everything after the first '.' and rev re-reverses the remnant. If you want to grep 'alma': ls -1 | rev | cut -f 2- -d "." | rev | grep 'alma'


-1

If you have acccess to sed, this is better as it will strip the last file extension, no matter what it is (png, jpg, tiff, etc...) ls | sed -e 's/\..*$//'


1

ls -l | sed 's/\.png$//' Is the most accurate method as highlighted by @roaima. Without the escaped \.png files named a_png.png would be listed as : a_.


20

ls -1 | sed -e 's/\.png$//' The sed command removes (that is, it replaces with the empty string) any string .png found at the end of a filename. The . is escaped as \. so that it is interpreted by sed as a literal . character rather than the regexp . (which means match any character). The $ is the end-of-line anchor, so it doesn't match .png in the ...


31

You only need the shell for this job. POSIXly: for f in *.png; do printf '%s\n' "${f%.png}" done With zsh: print -rl -- *.png(:r)



Top 50 recent answers are included