Can we do this in perl?

KarthicdotK :

I want the below awk one liner to be translated to perl. is it possible??

awk '{ for(i=1;i<=NF;i++){if(i==NF){printf("%s\n",$NF);}else {printf("%s\t",$i)}}}' file.txt |  awk 'NR > 1'

The first awk command removes the leading empty column and the next one removes the first line. Below is the head of file.txt

#FILEOUTPUT
       1    137442      2324
    2326    139767      4169
    6491    143936        94

The output i get from those commands is below

1       137442  2324
2326    139767  4169
6491    143936  94

Thanks, Karthic

Guss :

@Alex got the usage of $. correctly - which is not a very common perl idiom (though a useful one as we see), but they didn't handle the extra spaces correctly.

Awk is all about understanding what the fields are and then manipulating the fields, and as part of that it does a lot of whitespace canonalization.

Perl, OTOH, usually doesn't involve itself in field separation and a lot of users like to do that themeselves - but it does support this Awk behavior using the -a flag.

So a simple implementation of the above Awk line noise might look like this:

perl -anle 'print join("\t",@F) if $. > 1' file.txt

Explanation:

  • -a: trigger field separation using the default field separator (which works well in this case) or whatever -F says (like Awk).
  • -n : iterate over the input lines (same as what the outermost {} do in Awk). A common alternative is -p which would mean to iterate over the input lines and then print out whatever the line buffer has after running the code.
  • -l : When printing, add a new line at the end of the text (makes things like this slightly easier to work with)
  • -e : here's a script.

Then we just take the separated field array (@F) and join it. Often devs like to just address certain fields with $F[<index>], but here we don't need to loop - we can just take the list as is and pipe it to join().

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=33090&siteId=1