10

Following on from this question about stripping newlines out of text, I want to turn this into a zsh alias as follows:

alias striplines=' awk " /^$/ {print \"\n\"; } /./ {printf( \" %s \",$0);}"'

I've tried escaping the quotes inside the awk script, but I'm getting this error:

awk: (FILENAME=bspsrobustness FNR=1) fatal: division by zero attempted

(The file is called bspsrobustness)

Is there a way to do what I want? I suppose I could turn this into an awk script rather than a zsh alias, is that my best option?

  • By the way, this applies to all (Bourne-style, not csh) shells. – Gilles Feb 24 '11 at 20:27
9

You could use a zsh function instead of an alias. No quoting hoops to jump through.

striplines() {
    awk '... awk body "with quotes" ...' "$@"
}
  • And then how would I call it: striplines filename? – Seamus Feb 24 '11 at 15:03
  • could you explain what the "$@" is doing? – Seamus Feb 24 '11 at 15:10
  • @Seamus, yes you'd call it exactly like that. The "$@" syntax sends the striplines arguments to awk undisturbed -- necessary if, say, any of your filenames contain spaces: striplines "file 1" "file 2" would sent two filenames to awk. – glenn jackman Feb 24 '11 at 15:35
5

To get an idea of what's going on, run

% alias striplines='print -lr awk " /^$/ {print \"\n\"; } /./ {printf( \" %s \",$0);}"'
% striplines
awk
 /^$/ {print "\n"; } /./ {printf( " %s ",zsh);}

Since the $ characters are in double quotes (when they're expanded after the alias is expanded), they are interpreted by the shell. To get the quoting right, it's easier to put the whole alias definition in single quotes. What's inside the single quotes is what will be expanded when the alias is used. Now that the argument of awk is surrounded in double quotes, it's clear that you need backslashes before \"$.

alias striplines='print -lr awk " /^\$/ {print \"\n\"; } /./ {printf( \" %s \",\$0);}"'

A useful idiom to single-quote a single-quoted string is that '\'' is pretty much a way to put a literal single quote in a single-quoted string. Technically there's a juxtaposition of a single-quoted string, a backslash-quoted ', and another single-quoted string. The juxtaposed empty string '' at the end can be removed.

alias striplines='print -lr awk '\'' /^$/ {print "\n"; } /./ {printf( " %s ",$0);}'\'

After this long explanation, a recommendation: when it's too complicated for an alias, use a function.

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.