Search code examples
shellaliasfish

Fish Alias Not Saving Variable Calls


I currently use the command below to check a csv file for duplicates and this works just fine running it in the Fish shell. So now I'd like to save it as an alias but it strips away the variables from print.

Command used.

awk -F ',' '{print $2 $3}' Data.csv | sort -n | uniq -cd | sort -n

alias returned

awk -F ',' '{print }' Data.csv | sort -n | uniq -cd | sort -n

Obviously, this is not going to check any columns in the file. So how can variable calls be stored in alias functions.

I ran the command

alias --save data="awk -F ',' '{print $2 $3}' Data.csv | sort -n | uniq -cd | sort -n"

Solution

  • Fish, like other shells, expands variables in double-quotes.

    alias --save data="awk -F ',' '{print $2 $3}' Data.csv | sort -n | uniq -cd | sort -n"
    

    That "awk? That's double-quoting. That's also why the $2 and $3 will be colored like variables in an interactive fish session.

    So it runs the alias, but before it does that it replaces the values of $2 and $3, and since they aren't set it just ends up as nothing, so you get print .

    What you need is to either escape the $ of the variable expansion, or to use single-quoting, in which case you need to escape the ' quotes for the awk-call.

    So either

    alias --save data='awk -F \',\' \'{print $2 $3}\' Data.csv | sort -n | uniq -cd | sort -n'
    

    or

    alias --save data="awk -F ',' '{print \$2 \$3}' Data.csv | sort -n | uniq -cd | sort -n"
    

    Honestly, just do yourself a favor and make it a normal function:

    function data
        awk -F ',' '{print $2 $3}' Data.csv | sort -n | uniq -cd | sort -n
    end
    

    and then run funcsave data. This not only simplifies quoting but also allows you to put $argv wherever you want, so you could for example replace that Data.csv with $argv and run it as data Data.csv or data Data-2.csv or whatever.