I am very new to Perl. I need to extract arrays and print in the columns below. The tricky part is that each word has different pronunciation types ( which is specified in P or S) and each type is associated with its corresponding pronunciation and syllable shape.

I tried to extract by using array [ ], but the codes are fairly long. Is there a more efficient way to code it?

Input (the data is located in celex corpus). The following is one example of the thousands of lines.


  My Output needs to look like this:

WordForm   Frequency    Type      Pronunciation SyllableShape 

open         635       P.          [@U] [p@n]      [VV] [CVC]

open         635       P.          [@U] [pn,]          [VV] [CS] 

open         635       S           [@U] [pm,]          [VV] [CS] 



Not sure how you determine if there is a . after the P but, assuming these are all 4 element groups and a 5 element header, how about an awk solution?

awk -F '\' 'BEGIN{ print "WordForm Frequency Type Pronunciation Syllableshape"}{
     for (i=5;i<=NF;i+=4) print $2, $3, $i, $(i+3), $(i+2)
}' file | column -t


WordForm  Frequency  Type  Pronunciation  Syllableshape
open      635        P     [@U][p@n]      [VV][CVC]
open      635        P     [@U][pn,]      [VV][CS]
open      635        S     [@U][pm,]      [VV][CS]


As per the post below, and just for fun (because I have never even looked at perl for scripting purposes before last night) I have hammered the above loop into a perl script that seems to function. I am sure there is a lot wrong with the below because it was cobbled together from scratch with no knowledge. So if it is horribly poor coding, then please don't comment or criticise, just post the correct way to do it for my education too.


open(my $filehandle, '<', './file')
    or die "Unable to open file, $!";
    print "WordForm  Frequency  Type  Pronunciation  Syllableshape\n";
    while (<$filehandle>) { 
        @c = split (/\\/, $_);
        for ($i=4;$i<=(@c-4);$i+=4) {
            print "@c[1] @c[2] @c[$i] @c[$i+3] @c[$i+2]\n";
        print "\n";
    or warn "Unable to close the file handle: $!";
  • Thank you so much. If certain line contains 14 types of pronunciations (P or S) which will generate 14 rows of the 5 headers. Will the code still work? – AMH Nov 10 at 22:42
  • It iterates over the entire length of each line until it reaches the end before going on to the next line, so yes, it should do. – bu5hman Nov 10 at 23:02
  • You are awesome! Thank you so much! – AMH Nov 10 at 23:17
  • Hi, I tried a different approach by adopting your concept but using loop and "for" in perl. But it won't run. Can you check if there is logic issue in my codes so it will not iterate. – AMH Nov 11 at 13:46
  • Here is the code. open my $f, '<' ,"/corpora/celex release 2/english/epl/epl.cd " or die "No file!"; open my $o, '>', "epl.cd"; print $o "WordForm\tFrequency\tType\tPronounciation\tSyllableShape\n"; while(<$f>) { $line = $_; chomp($line); @Array = split(/\. ?/,$line) for($i = 5; $i <=$numbers_of_arrays) { print $o “$Array[2]” . "\t" . “$Array[3]” . "\t" . “$i” . “\t” . “$[i+3]”. “\t” . “$[$i+2”. $i = $i +4; } print $o "\n"; } close($f); close($o); – AMH Nov 11 at 13:52

I simplified the perl script a bit. This "script" can be called with perl script file.

print "WordForm Frequency  Type  Pronunciation  Syllableshape\n";
while (<>) {
        @c = split(/\\/);
        for ($i=4; $i<$#c; $i+=4) {
            print "$c[1] $c[2]";
            print " $c[$i] $c[$i+3] $c[$i+2]\n";

$i<$#c; instead of $i<@c-4;: I left out that "safety" minus 4 (matters only if records are broken).

$#c is the array @c as scalar value i.e. last index.

The only difference to awk (i=5) is the $i=4, because the first element is $c[0] in perl.

  • Thank you. I tried the codes above but wasn't successful because Perl did not accept math such as $c [$I + 3]. I modified your codes and the system gave me ssf syntax errors. I am showing my codes below. – AMH Nov 12 at 2:24
  • Syntax error at epl.cd line 26 near “4;” Syntax error at epl.cd line 26 near “4) ” Unrecognized character \xE2; marked by < = HERE after $c [1] < = HERE near column 59 at epl.cd line 29 while(<$f>) { $line = $_; chomp($line); @c = split(/ /, $line) for($i = 4; $j = $i + 3; $k = $i + 2; $i <=$#c; $i+=4) { print $o $c[1] . "\t" . $c[2] . "\t" . $c[$i] . “\t” . $c[$j]. “\t” . $c[$k] . “\n”;. } } close($f); close($o); – AMH Nov 12 at 2:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.