Question

I am new to grep and awk - using Windows 7 (I downloaded grep and awk for windows from GnuWin).

I am have having trouble running this script:

grep -Fwf dictionary.txt frequency.txt | awk '{print $2 "," $1}'

I get the error:

awk: '{print
awk: ^ invalid char ''' in expression

I believe it might have something to do with having to use double quotes in Windows, but I tried all the combinations I can think of and still it doesn't work.

Can anyone help? Thanks

Was it helpful?

Solution

Escaping command line items is always a pain on Windows. As a last resort you could probably use gawk -f!

So: your file script.awk contains:

print $2,$1

And you do grep -Fwf dictionary.txt frequency.txt | awk -f script.awk

OTHER TIPS

On Windows, you need to use double quotes to quote your awk commands. So

grep -Fwf dictionary.txt frequency.txt | awk '{print $2 "," $1}'

needs to be changed to

grep -Fwf dictionary.txt frequency.txt | awk "{print $2 "," $1}"

But remember, you can't use double quotes inside double quotes, you need to escape them. On Windows you can't simply use \ to escape it. You need the following syntax:

grep -Fwf dictionary.txt frequency.txt | awk "{print $2 \"",\"" $1}"

Right, that's \"" to represent " inside double quotes.

You need to use double quotes around your awk script and escape the embedded quotes in the print statement using a good old backslash: [g]awk "BEGIN {print \"Hello escape char!\"}"

Here is a short example which will accept an input.csv , then output new.csv:

gawk < input.csv -F, "{print $1 \"",\"" $5} ">new.csv

Since the brackets must be within double quotes, three sets of double quotes are required inside the bracketed expression.

For example:

gawk "{print $2 """,""" $1}"

I have stuggled over the years to get AWK running under windows. There are problems with quoting and path delimiters. My final solution is to "let AWK fly free", that is free from the command line. I understand that it was developed as a glue for unix style command line juju, but I just wanted to use it as a scripting language.

All my AWK scripts contain a list of targets and a defined output file. They can be run by double clicking through an associated DOS batch file:

: AWK.BAT - place in the same directory as GAWK
@echo off

:Check %1 in not null
If [%1]==[] (
    cls
    Echo No parameters passed
    goto End
)

: Change to the parameter file location
cd /D "%~dp1"

: Set PrintFile - this will be the name of the script (not the target file) with ".out"
Set PrintFile=%~nx1.out

:Run AWK
:   -v PrintFile to allow renaming of output file
:   -f ScriptFile.awk the program
:   > Redirects output to a known destination
cls
P:\MyPrograms\EDITORS\Addins\gawk\gawk.exe  -v PrintFile=%PrintFile% -f %* >%PrintFile%

:End
pause

An example of my AWK scripts is presented below (extract all lines with ::tab and print them):

# AWK Template

BEGIN{
    ## Hard Code Target Files - Unix paths with / separators ##
    #   Realtive paths from the location of ScriptFileName.awk
    #   These will be added to the end of the ARG array - after any command line target files
    AddTarget("../APEdit.ahk")

    ## Hard Code Output Files - WinDos paths with \\ separators ##
    #   Realtive paths from the location of ScriptFileName.awk
    #   Default is ScriptFileName.awk.out passed in as a variable called PrintFile
    #   PrintFile will be copied to OutputFile after processing using the END section
    OutputFile = "Keys.txt"

    # Set input record sep and field sep
    RS="\n"
    FS=" "

    # Set output RS and FS
    ORS="\n"
    OFS=" " 

    # Write a header
    print "Key assignments from the source code"
    print " "
}

## MIDDLE - Once per matching record! ## 

# Find autohotkey key definitions
/::\t/ { 
    print $0
}

END{

    ## Rename output files
    if (OutputFile) {
        system("Copy /Y " PrintFile "  " OutputFile)
    }
}

## Functions ##
function AddTarget(FN){
    # Need to check file exists
    if (FileExists(FN)){
        ARGV[ARGC] = FN
        ARGC ++
    }
}

function FileExists(FN) {
    if ((getline < FN) > 0) {
        close(FN);
        return 1
    } else {
        print "Target file not found " FN > "error.awk.txt"
        return ""
    }
}

You can see this defines the input target within the script and defines the final output target within the script. It uses a temp ".out" file to avoid lots of print redirection, copying the file to the desired output in the END section of the script.

I have associated AWK files with this batch file and added an option in my editor to send AWK files to the batch file.

Kind Regards

Yousui said:

... you can't use double quotes inside double quotes, you need to escape them. On Windows you can't simply use \ to escape it.

while ReluctantBIOSGuy has used just \" in his example.

I tried both \"" and \", and both works for me (gawk under Windows XP both on the command line and in a batch file).

Here is an example involving " in the output (a string literal in c code):

FCIV\fciv -add ..\07-Sources -type *.h -type *.c -bp ..\07-Sources | find /V "//" | sort /+33 > listof.md5
FCIV\fciv -add listof.md5 | find /V "//" | gawk "{print \"static const char md5[] = \\\"\" $1 \"\\\";\"}" > ..\07-Sources\generated\md5.c
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top