0

Subject: one-liner smart Perl command instead of a simple grep (in Bash script)

I have a problem when I use grep to match the unusual characters (I can't put the "\" before each unusual character, because it's very problematic and not a smart solution).

I need Perl one-liner syntax that match exactly all the unusable characters as defined in the $Some_string. Examples: 

Examples

Some_string="[234-094]"
Some_string="[ * ( & % @ !]"
Some_string="~ [ 0:3 # % & ^ + =]"
Some_string="1.1.1.1.-9.9.9.9   + 9999.999.1 – 10000"
Some_string="< { [ ' : ; " ? / . , "
Some_string="PORT.A.B.C.D – 124.543.455.33 – [ ! NOT EQUAL PORT 38737 – 3837652"
.
.
.

My bad grep syntax

 cat  file | grep $Some_string

With Perl (I need the following right suggestion/solution):

 cat file | perl -nle 'print if /$Some_string/'

Rules

Remark: if Some_string="111.111.111.111" and in the file I have 1111.1111.1111.1111 then the Perl syntax needs to ignore this. Perl must match only if I have this in the file: 111.111.111.111 .

Second remark: if Some_string="WORD" and in the file I have: ONEWORD then the Perl syntax needs to ignore this. Perl must match only if I have this in the file: WORD

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jon
  • 903
  • 5
  • 14
  • 21

3 Answers3

2

I'm not sure I understand your question, exactly. Perhaps -P and -x do what you want, along with quoting "$Some_string" to preserve whitespace?

grep -Px "$Some_string" file

From the grep man page:

-P, --perl-regexp

Interpret PATTERN as a Perl regular expression.

-x, --line-regexp

Select only those matches that exactly match the whole line.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • 1
    please advice about the perl , I think perl is more safe – jon Nov 17 '10 at 19:36
  • You need to explain your problem better. I don't understand what you're trying to do, nor how Perl will help. Please add some examples or something. – John Kugelman Nov 17 '10 at 19:42
  • 1
    please see the Some_string examples , I need to perfrom cat file and to match the $Some_string , but with perl only - one line syntax , also see my last remark – jon Nov 17 '10 at 19:47
  • like this: cat file | perl ……../$Some_string/ – jon Nov 17 '10 at 19:51
  • @jon: Do you know about `quotemeta()`, or its double-quoted string-escape version, `\Q...\E`? – tchrist Nov 17 '10 at 20:10
  • no I dont but please give me example , I think "\Q" and "E" are the part of my perl solution -:) – jon Nov 17 '10 at 20:14
  • @jon, you’re going to have to tell us what part of [*perlre*](http://perldoc.perl.org/perlre.html)’s discussion of `\Q` and *perlfunc* ’s corresponding description of [`quotemeta`](http://perldoc.perl.org/functions/quotemeta.html) it is is that you *don’t* understand in the examples included there about this particular matter. You’ll need [some command-line switches](http://perldoc.perl.org/perlrun.html#Command-Switches]) for a one-liner; these are documented in the *perlrun* manpage on your own system. – tchrist Nov 17 '10 at 20:37
  • OK I find the follwoing perl -nle 'print if /\Q$ENV{Some_string}/' but how to match exactly the string? – jon Nov 17 '10 at 21:14
  • for example if in file I have 1.node_name and Some_string=node_name then it will match but I dont want to match 1.node_name ? what to do? – jon Nov 17 '10 at 21:15
  • another example if I have in the file 11.11.11 and I want to match 1.1.1 in this case my perl syntax will match this also -:( – jon Nov 17 '10 at 21:17
  • please see the RULES in my quastion. – jon Nov 17 '10 at 21:23
  • @jon - Have you tried this `grep -Px` command? If it doesn't do what you want please give examples of strings that don't work. – John Kugelman Nov 17 '10 at 22:32
  • grep x also match spaces , this is the reason that I cant use grep -x – jon Nov 19 '10 at 07:45
0

You will have to escape the string somehow. Using \ to escape special characters is required in this case, because passing the string to Perl is really no different than passing it to grep -- both will see the string after the shell processes it.

Using Perl to do this will simply obfuscate your code.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • sorry I dont want to use with "\" please advice about perl. – jon Nov 17 '10 at 19:26
  • 1
    You have no choice. If you are going to pass these special characters to perl, **you will still have to escape them**. – cdhowie Nov 17 '10 at 19:27
  • I dont think so, because perl have special re to ignore the unusable char – jon Nov 17 '10 at 19:29
  • Yes, but you still have to pass the string containing the characters to perl. And if you use characters that the **shell** wants to interpret (like `"`) you *still* have to escape them. – cdhowie Nov 17 '10 at 19:34
  • 1
    `perl -nle 'BEGIN { $pat = shift || die } print if /\Q$pat/' pattern_with_ugly_things_in_it file1 file2 file666` – tchrist Nov 17 '10 at 20:09
  • You're still going to have to escape characters in the pattern. – cdhowie Nov 17 '10 at 20:14
  • your perl syntax not have the rules that need to match exactly the string – jon Nov 19 '10 at 07:50
0

You could do something like this:

perl -ne 'print if m|\Q[ * ( & % \E\@\Q !]\E|' file

I've found the \Q and \E operator in Quote and Quote-like Operators.

A snippet from that link:

You cannot include a literal $ or @ within a \Q sequence. An unescaped $ or @ interpolates the corresponding variable, while escaping will cause the literal string \$ to be inserted. You'll need to write something like m/\Quser\E@\Qhost/.

\Q  Quote (disable) pattern metacharacters till \E or
    end of string

\E  End either case modification or quoted section
    (whichever was last seen)
sid_com
  • 24,137
  • 26
  • 96
  • 187
  • hi - Unrecognized switch: -E ( the E flag isnt valid in the perl syntax) – jon Nov 19 '10 at 07:46
  • It worked fine with Perl v5.28.1 (stock [Ubuntu 19.10](https://en.wikipedia.org/wiki/Ubuntu_version_history#Ubuntu_19.10_(Eoan_Ermine))). The output was one line, `Some_string="[ * ( & % @ !]"`. Though it also appeared as if there was an empty line after that line. – Peter Mortensen Dec 13 '19 at 18:56