Memo: perl tips

메모 2011. 6. 16. 18:26

http://www.perlhowto.com/one_liners

http://perldoc.perl.org/perlre.html

Perl specail variables: http://perldoc.perl.org/perlvar.html#General-Variables

/usr/bin/perl -p -i -e "s/$1/$2/g" $3

 

디렉토리 내의 모든 py 파일의 tearDown(self): 메쏘드에 self.delete_cache() 를 호출하는 부분 추가

find . -name '*.py' -exec /usr/bin/perl -p -i -e 's/tearDown\(self\):(?!.*tearDown\(self\):)/$&\n        self.delete_cache()/s' {} \;

 

중간의 어떤 값을 빼서 맨 뒤로 돌림:

perl -p -i -e "s/(.*)('This is Subject')(, )(.*)(\],$)/\1\4 ,\2],/g"

입/출력

입력: ['19', '1', 'MID19', 'This is Subject', 'Y', '1019', 'Y', '5'],

----->

출력: ['19', '1', 'MID19', 'Y', '1019', 'Y', '5' ,'This is Subject'],

 

Deleting matching lines:

 

Perl does not have sed's g/re/d, which deletes entire line if the line matches pattern.
You're gonna need some trick(?):
Perl's command line option -n tells perl to just execute commands for every line (without printing the line processed), while -p option executes command AND PRINT the line processed. You could use it to delete matching lines:

perl -n -i -e 'print unless /make_more_abridged_response/' filename.py

perl command line options -p and -n (from perlrun manpage):

       -n   causes Perl to assume the following loop around your program, which makes it iterate over filename
            arguments somewhat like sed -n or awk:

              LINE:
                while (<>) {
                    ...             # your program goes here
                }

            Note that the lines are not printed by default.  See -p to have lines printed.  If a file named by an
            argument cannot be opened for some reason, Perl warns you about it and moves on to the next file.

            Also note that "<>" passes command line arguments to "open" in perlfunc, which doesn't necessarily
            interpret them as file names.  See  perlop for possible security implications.

            Here is an efficient way to delete all files that haven't been modified for at least a week:

                find . -mtime +7 -print | perl -nle unlink

            This is faster than using the -exec switch of find because you don't have to start a process on every
            filename found.  It does suffer from the bug of mishandling newlines in pathnames, which you can fix if
            you follow the example under -0.

            "BEGIN" and "END" blocks may be used to capture control before or after the implicit program loop, just
            as in awk.

       -p   causes Perl to assume the following loop around your program, which makes it iterate over filename
            arguments somewhat like sed:

              LINE:
                while (<>) {
                    ...             # your program goes here
                } continue {
                    print or die "-p destination: $!\n";
                }

            If a file named by an argument cannot be opened for some reason, Perl warns you about it,
            and moves on to
the next file.  Note that the lines are printed automatically. 
            An error occurring during printing is
treated as fatal.  To suppress printing use the -n switch. 
            A -p overrides a -n switch.


            "BEGIN" and "END" blocks may be used to capture control before or after the implicit loop, just as in
            awk.

 

Adding lines to multiple files:

perl -pi -le 'print "/*\n * \$Id\$\n *\n * vim 설정\n * vim:ts=4:shiftwidth=4:et:cindent:fileencoding=utf-8:\n */\n" if $. == 1; close ARGV if eof' $(cat filelist.txt)

if 관련 바꾸기

find src -name '*.cpp' -exec perl -p -i -e "s/if\s*\(\s*(.*) \)\s*$/if \(\1\)\n/g" {} \;

Exact word matching

Just wrap pattern with '\b': 's/\bint\b/int32_t/g'

 

Revoming trailing white space

find . -name '*hpp' -exec /usr/bin/perl -p -i -e 's/ +$//g' {} \;

 

Matching as few characters as possible (non-greedy regex)

$ echo "http://orchistro.tistory.com/" | perl -pe "s/http:.*\//THIS/g"

THIS

$ echo "http://orchistro.tistory.com/" | perl -pe "s/http:.*?\//THIS/g"

THIS/orchistro.tistory.com/

 

Just adding '?' after * will do the magic.

 

 

Multiline matching / replacing

/usr/bin/perl -i -0pe 's/.*needle.*\n.*\n.*\n.*\n.*\n.*inthehaystack="50".*//' file.txt

 

: