Reputation: 560
I'm new in using regex, hope someone can help me. I'm using the regex below to grep a csv file for string that exactly has one pipe character (i.e. |)
grep "^([^\\|]+\\|){1}[^\\|]+$" myfile.csv
Unfortunately, the above yields no result when used with grep. Any ideas?
A sample csv file content is as below, where I expect the 2nd line to be found.
"foo"|"foo"|"foo"
"bar"|"bar"
Solutions to this question:
grep -E "^([^|]+\|){1}[^|]+$" myfile.csv
and
egrep "^[^|]+\|[^|]+$" myfile.csv
Upvotes: 2
Views: 2477
Reputation: 64002
Grep and regexes are the wrong tool for this task. Use something that is intended for counting:
# Use a split function with the pipe as delimiter
awk 'split($0, _, "|") == 2 {print}' the_file
# Set awk's field separator to the pipe character
# and check the number of fields on each line
awk -F'|' 'NF == 2 {print}' the_file
Upvotes: 0
Reputation: 560
Here are the solutions to my question. Thanks to the comments that led me to solving this.
grep -E "^([^|]+\|){1}[^|]+$" myfile.csv
and
egrep "^[^|]+\|[^|]+$" myfile.csv
Upvotes: 0
Reputation: 41446
Solution using awk
awk 'gsub(/\|/,"|")==1' file
gsub(/\|/,"|")
this counts number of |
replaced, if this equal 1
, then do default action, print $0
Edit:Another awk:
awk 'split($0,a,"|")==2' file
Count how many parts text is dived into by |
, if 2
print.
Upvotes: 1
Reputation: 129497
You can try:
^[^|]*\|[^|]*$
You don't need to escape |
in a character class. Also you presumably want *
instead of +
here to allow for strings like |abc
, xyz|
, and just |
on its own.
Upvotes: 5