How to exclude hyphen as word separator in bash - bash
I am unable to grep for exact word match containing hyphen as in
/home/imper-home,3,0,0,0,jim.imper,NONE,NONE,NONE,http://sanjose
/home/imper,15,10,3,30,jim.imper,NONE,NONE,NONE,http://sanjose-age
I tried
grep -w imper
but it returns both /home/imper-home and /home/imper.
I want only /home/imper-home to returned by using,
grep -wv /home/imper
This will work in general:
word=imper
grep -w "$word" file | grep -v "$word-"
Related
How to grep only matching string from this result?
I am just simply trying to grab the commit ID, but not quite sure what I'm missing: ➜ ~ curl https://github.com/microsoft/vscode/releases -s | grep -oE 'microsoft/vscode/commit/(.*?)/hovercard' microsoft/vscode/commit/ccbaa2d27e38e5afa3e5c21c1c7bef4657064247/hovercard The only thing I need back from this is ccbaa2d27e38e5afa3e5c21c1c7bef4657064247. This works just fine on regex101.com and in ruby/python. What am I missing?
If supported, you can use grep -oP echo "microsoft/vscode/commit/ccbaa2d27e38e5afa3e5c21c1c7bef4657064247/hovercard" | grep -oP "microsoft/vscode/commit/\K.*?(?=/hovercard)" Output ccbaa2d27e38e5afa3e5c21c1c7bef4657064247 Another option is to use sed with a capture group echo "microsoft/vscode/commit/ccbaa2d27e38e5afa3e5c21c1c7bef4657064247/hovercard" | sed -E 's/microsoft\/vscode\/commit\/([^\/]+)\/hovercard/\1/' Output ccbaa2d27e38e5afa3e5c21c1c7bef4657064247
The point is that grep does not support extracting capturing group submatches. If you install pcregrep you could do that with curl https://github.com/microsoft/vscode/releases -s | \ pcregrep -o1 'microsoft/vscode/commit/(.*?)/hovercard' | head -1 The | head -1 part is to fetch the first occurrence only. I would suggest using awk here: awk 'match($0,/microsoft\/vscode\/commit\/[^\/]*\/hovercard/){print substr($0,RSTART+24,RLENGTH-34);exit}' The regex will match a line containing microsoft\/vscode\/commit\/ - microsoft/vscode/commit/ fixed string [^\/]* - zero or more chars other than / \/hovercard - a /hovercard string. The substr($0,RSTART+24,RLENGTH-34) will print the part of the line starting at the RSTART+24 (24 is the length of microsoft/vscode/commit/) index and the RLENGTH is the length of microsoft/vscode/commit/ + the length of the /hovercard. The exit command will fetch you the first occurrence. Remove it if you need all occurrences.
You can use sed: curl -s https://github.com/microsoft/vscode/releases | sed -En 's=.*microsoft/vscode/commit/([^/]+)/hovercard.*=\1=p' | head -n 1 head -n 1 is to print the first match (there are 10)grep -o will print (only) everything that matches, including microsoft/ etc. Your task can not be achieved with Mac's grep. grep -o prints all matching text (compared to default behaviour of printing matching lines), including microsoft/ etc. A grep which implemented perl regex (like GNU grep on Linux) could make use of look ahead/behind (grep -Po '(?<=microsoft/vscode/commit/)[^/]+(?=/hovercard)'). But it's just not available on Mac's grep.
On MacOS you don't have gnu utilities available by default. You can just pipe your output to a simple awk like this: curl https://github.com/microsoft/vscode/releases -s | grep -oE 'microsoft/vscode/commit/[^/]+/hovercard' | awk -F/ '{print $(NF-1)}' ccbaa2d27e38e5afa3e5c21c1c7bef4657064247 3a6960b964327f0e3882ce18fcebd07ed191b316 f4af3cbf5a99787542e2a30fe1fd37cd644cc31f b3318bc0524af3d74034b8bb8a64df0ccf35549a 6cba118ac49a1b88332f312a8f67186f7f3c1643 c13f1abb110fc756f9b3a6f16670df9cd9d4cf63 ee8c7def80afc00dd6e593ef12f37756d8f504ea 7f6ab5485bbc008386c4386d08766667e155244e 83bd43bc519d15e50c4272c6cf5c1479df196a4d e7d7e9a9348e6a8cc8c03f877d39cb72e5dfb1ff
GREP: is there a way to use grep inserting a text between filename and the pattern?
I have grep --color -EH "^([^,]*\,){3}5" try.csv and the output it does is this: try.csv:410,30151010,K,5001,,,,,,,,,,,,,,,,,,,,,,,,,,,,,512 try.csv:652,20151010,K,5001,,,,,,,,,,,,,,,,,,,,,,,,,,,,,41 try.csv:109,30151010,R,5005,,,,,,,,,,,,,,,,,,,,,,,,,,,,,455 I tried grep --color -EH "^([^,]*,){3}5" try.csv | perl -ne 'print ",$_"' but the output looks like this : ,try.csv:410,30151010,K,5001,,,,,,,,,,,,,,,,,,,,,,,,,,,,,512 ,try.csv:652,20151010,K,5001,,,,,,,,,,,,,,,,,,,,,,,,,,,,,41 ,try.csv:109,30151010,R,5005,,,,,,,,,,,,,,,,,,,,,,,,,,,,,455 Expected output: try.csv:,410,30151010,K,5001,,,,,,,,,,,,,,,,,,,,,,,,,,,,,512 try.csv:,652,20151010,K,5001,,,,,,,,,,,,,,,,,,,,,,,,,,,,,41 try.csv:,109,30151010,R,5005,,,,,,,,,,,,,,,,,,,,,,,,,,,,,455 I am very new to Perl and shell. I'm searching in the CSV files.
You may insert a comma by using sed, $ grep --color -EH "^([^,]*\,){3}5" try.csv | sed 's/:/&,/' s/:/&,/: the the special character & in the replacement refers to that portion of the string which matched. And you may add a comma behind & to meet your requirement.
grep up to and including equal sign for CLI parameter
My goal is to match a command line argument prefix that looks like: --abc= Both of the patterns below (and many others), allow: --abc== Somehow, I can't find a grep way to ensure there is just one equal sign. grep -i '^--[a-z]\{2,\}=\{1,1\}' grep -i '^--[a-z]\{2,\}=' grep 2.20 CentOS Linux 7.3.1611
ERE: ^--[[:alpha:]]{2,}=[^=]+$ ^--[[:alpha:]]{2,}= matches --, then two or more alphabetic characters in your locale, then a literal = [^=]+$ matches one or more characters that are not = at the end BRE: ^--[[:alpha:]]\{2,\}=[^=]\+$ Example: $ grep -E '^--[[:alpha:]]{2,}=[^=]*$' <<<'--foobar=spam' --foobar=spam $ grep -E '^--[[:alpha:]]{2,}=[^=]*$' <<<'--foobar=23' --foobar=23 $ grep -E '^--[[:alpha:]]{2,}=[^=]*$' <<<'--123ad=' $ grep -E '^--[[:alpha:]]{2,}=[^=]+$' <<<'--spamegg='
How to grep and match the first occurrence of a line?
Given the following content: title="Bar=1; Fizz=2; Foo_Bar=3;" I'd like to match the first occurrence of Bar value which is 1. Also I don't want to rely on soundings of the word (like double quote in the front), because the pattern could be in the middle of the line. Here is my attempt: $ grep -o -m1 'Bar=[ ./0-9a-zA-Z_-]\+' input.txt Bar=1 Bar=3 I've used -m/--max-count which suppose to stop reading the file after num matches, but it didn't work. Why this option doesn't work as expected? I could mix with head -n1, but I wondering if it is possible to achieve that with grep?
grep is line-oriented, so it apparently counts matches in terms of lines when using -m[1] - even if multiple matches are found on the line (and are output individually with -o). While I wouldn't know to solve the problem with grep alone (except with GNU grep's -P option - see anubhava's helpful answer), awk can do it (in a portable manner): $ awk -F'Bar=|;' '{ print $2 }' <<<"Bar=1; Fizz=2; Foo_Bar=3;" 1 Use print "Bar=" $2, if the field name should be included. Also note that the <<< method of providing input via stdin (a so-called here-string) is specific to Bash, Ksh, Zsh; if POSIX compliance is a must, use echo "..." | grep ... instead. [1] Options -m and -o are not part of the grep POSIX spec., but both GNU and BSD/OSX grep support them and have chosen to implement the line-based logic. This is consistent with the standard -c option, which counts "selected lines", i.e., the number of matching lines: grep -o -c 'Bar=[ ./0-9a-zA-Z_-]\+' <<<"Bar=1; Fizz=2; Foo_Bar=3;" yields 1.
Using perl based regex flavor in gnu grep you can use: grep -oP '^(.(?!Bar=\d+))*Bar=\d+' <<< "Bar=1; Fizz=2; Foo_Bar=3;" Bar=1 (.(?!Bar=\d+))* will match 0 or more of any characters that don't have Bar=\d+ pattern thus making sure we match first Bar=\d+ If intent is to just print the value after = then use: grep -oP '^(.(?!Bar=\d+))*Bar=\K\d+' <<< "Bar=1; Fizz=2; Foo_Bar=3;" 1
You can use grep -P (assuming you are on gnu grep) and positive look ahead ((?=.*Bar)) to achieve that in grep: echo "Bar=1; Fizz=2; Foo_Bar=3;" | grep -oP -m 1 'Bar=[ ./0-9a-zA-Z_-]+(?=.*Bar)'
First use a grep to make the line start with Bar, and then get the Bar at the start of the line: grep -o "Bar=.*" input.txt | grep -o -m1 "^Bar=[ ./0-9a-zA-Z_-]\+" When you have a large file, you can optimize with grep -o -m1 "Bar=.*" input.txt | grep -o -m1 "^Bar=[ ./0-9a-zA-Z_-]\+"
grepping string from long text
The command below in OSX checks whether an account is disabled (or not). I'd like to grep the string "isDisabled=X" to create a report of disabled users, but am not sure how to do this since the output is on three lines, and I'm interested in the first 12 characters of line three: bash-3.2# pwpolicy -u jdoe -getpolicy Getting policy for jdoe /LDAPv3/127.0.0.1 isDisabled=0 isAdminUser=1 newPasswordRequired=0 usingHistory=0 canModifyPasswordforSelf=1 usingExpirationDate=0 usingHardExpirationDate=0 requiresAlpha=0 requiresNumeric=0 expirationDateGMT=12/31/69 hardExpireDateGMT=12/31/69 maxMinutesUntilChangePassword=0 maxMinutesUntilDisabled=0 maxMinutesOfNonUse=0 maxFailedLoginAttempts=0 minChars=0 maxChars=0 passwordCannotBeName=0 validAfter=01/01/70 requiresMixedCase=0 requiresSymbol=0 notGuessablePattern=0 isSessionKeyAgent=0 isComputerAccount=0 adminClass=0 adminNoChangePasswords=0 adminNoSetPolicies=0 adminNoCreate=0 adminNoDelete=0 adminNoClearState=0 adminNoPromoteAdmins=0 Your ideas/suggestions are most appreciated! Ultimately this will be part of a Bash script. Thanks.
This is how you would use grep to match "isDisabled=X": grep -o "isDisabled=." Explanation: grep: invoke the grep command -o: Use the --only-matching option for grep (From grep manual: "Print only the matched (non-empty) parts of a matching line, with each such part on a separate output line." "isDisabled=.": This is the search pattern you give to grep. The . is part of the regular expression, it means "match any character except for newline". Usage: This is how you would use it as part of your script: pwpolicy -u jdoe -getpolicy | grep -oE "isDisabled=." This is how you can save the result to a variable: status=$(pwpolicy -u jdoe -getpolicy | grep -oE "isDisabled=.") If your command was run some time prior, and the results from the command was saved to a file called "results.txt", you use it as input to grep as follows: grep -o "isDisabled=." results.txt
You can use sed as cat results.txt | sed -n 's/.*isDisabled=\(.\).*/\1/p' This will print the value of isDisbaled.