Perl One-Liner Like Grep

perl one-liner like grep?


(echo a; echo b; echo c) | perl -ne 'print if /a/'

Filtering a list of files with a perl one-liner

Despite some issues in your examples, I couldn't reproduce your problem.

For command ls | grep -P ZZZZZTYT.vcf.gz works and ls | grep -P ZZZZZTYT.vcf.gz$ don't, my first guess it's you have whitespaces or other "invisible" characters at the end your file. You can try ls | cat -A (or cat -veT) to see if in fact there more than you can see. Anyway your regex can be better written with literal dots (\.), as . alone matches anything.

In your perl onliners, you are trying to print $1 and this variable is empty, from the perldoc perlvar:

$<digits> ($1, $2, ...)
Contains the subpattern from the corresponding set of capturing
parentheses from the last successful pattern match, not counting
patterns matched in nested blocks that have been exited already.

These variables are read-only and dynamically-scoped.

Mnemonic: like \digits.

I think you want print $_, this variable holds the content of current line when you use -n switch (references in perlvar and perlfunc). Than you could rewrite your perl oneliner as:

ls | perl -ne'/\.gz$/ or print' # for not .gz files

or

ls | perl -ne'/\.gz$/ and print' # list .gz files

Using your examples, it is enough to remove the $1 from the online.

As already pointed you need to check if there is something at the end of your filenames.

If there "bad characters" at the and of your filenames, this oneliner will work for listing .gz files:

ls | perl -ne'/\.gz.*$/ and print'

What is perl's equivalent one liner of grep -o

If you want to do the minimal amount of work, change

grep -o -P 'PATTERN' file

to

perl -nle'print $& if m{PATTERN}' file

So from

grep -o -P '(?<=foo)bar(?=baz)' file

you get:

perl -nle'print $& if m{(?<=foo)bar(?=baz)}' file

However, it can be simpler to use a capture.

perl -nle'print $1 if /foo(bar)baz/' file

How can I get my Perl one-liner to show only the first regex match in the file?

Add and last to your one-liner like so (extra quotes removed):

perl -ne 'print $1 and last if /KEY1="(.*?)"/' myfile

This works because -n switch effectively wraps your code in a while loop. Thus, if the pattern matches, print is executed, which succeeds and thus causes last to be executed. This exits the while loop.

You can also use the more verbose last LINE, which specifies the (implicit) label of the while loop that iterates over the input lines. This last form is useful for more complex code than you have here, such as the code involving nested loops.

How can I pipe the results of grep to a perl one liner?

With the $(...) bash syntax.

perl -p -i.bak -e 's{/env/file1/}{/env/file2/}g' $(grep -Irc "/env/file1/" /env/scripts/ | cut -d':' -f1 | sort | uniq)

translate pcregrep into Perl one-liner

Since output of ifconfig normally has a multiline block of text for each interface, all separated by blank lines, it is convenient to read it in paragraphs (-00). Then the rest simplifies a lot

ifconfig -a | perl -00 -nE'say $1 if /^(.+?)\s*:.*?status:\s+active/s'

We still need the /s modifier, making . match a newline as well, as each paragraph itself is a multiline string and the pattern needs to match across multiple lines.


Except that it doesn't on the MacOS used for this question -- there are no blank lines separating blocks for interfaces. Then there is no point in seeking paragraphs (breaking on newline which isn't) and this answer doesn't work for that system.

Here is then a classic line-by-line approach that does -- set the interface name at the first line for that interface's output (no spaces at line beginning), then test for active status

perl -wnE'$ifn=$1, next if /^(\S[^:]+?)\s*:/; say $ifn if /status:\s+active/' file

This allows spaces inside an interface name, what is very unlikely (and perhaps not even allowed). For a more restrictive pattern, which doesn't allow spaces in the name, use /^(\S+?)\s*:/ (or the more efficient /^([^:\s]+)/). The \s* and the preceding ? are there only to make it not capture the trailing spaces (right before :), if any were possible.

This works in the case when there are empty lines between interface blocks as well.

How to use Perl command one-liner to extract a string starting with x and ending with y

You should enclose the regex pattern in slashes instead:

perl -ne '/vcm-[0-9]+\.blah\.edu/&&print"$&\n"' nmap.txt


Related Topics



Leave a reply



Submit