i have functions in my awk script to parse lines contains certain words/characters
function tohyphen (o) {
split ($0,a,"to[-_]")
split (a[2],b,"-")
k=b[1]
p=b[2]
return k
}
function tospace (o) {
split ($0,a,"to ")
split (a[2],b,"-")
k=b[1]
p=b[2]
return k
}
funtion pipe (o) {
split ($0,a,"|")
split (a[2],b,"-")
x=b[1]
y=b[2]
return x
#return x
}
{
#if (match ($0, /to[-_]/))
if ($0 ~ /to[-_]/)
print "found to- for interface ", $1, " is ", tohyphen($0), "is ",p, " is ", $1="",$0
else if ($0 ~ /to /)
#(match ($0, /to /))
print "found to for interface", $1, " is ", tospace($0), " is ", p, " is ", $1="",$0
else if ($0 ~ /\|/)
# pipe($0)
print "found to for interface", $1, " is ",topipe($0), " is ", y, " is ", $1="",$0
else
print $1, $1="",$0
}
in the third function which just searches for a match to pipe it does not allow me return anything, giving me the error return is outside of function.
any idea what could be the problem or any other way for me to run this.
Try spelling function correctly! You have funtion not function. Are you using an editor with syntax highlighting for awk? You can see from stackoverflows markup that funtion is not a reserved word.
Related
Is there a way in an awk one-liner to cover both the positive and negative match case with different print statements?
To illustrate. Let's say I have a file where I want to prepend a set of words with '#' but still want to print all the words in the file.
Something like :
awk '/red/||/green/ { print "# My mod : " $0 } else { print $0 }'
Of course the above wont work. But what's the simple way to do this in awk.
Cheers,
Gert
To cover the general case i.e. printing something completely different, you can use next:
awk '/red|green/ { print "foo"; next } { print "bar" }' file
The second block is only reached if the first pattern is false.
You can also use if/else within a single action block.
For your specific case, where you are just adding to the record and printing, you can use this:
awk '/red|green/ { $0 = "# My mod : " $0 } 1' file
The 1 at the end ensures that every record is printed.
How about "painful" long hand
awk '{if (/red/||/green/ ) { print "# My mod : " $0 } else { print $0 }}'
That works for me ;-), but you can save a few chars typing with
awk '{if (/red|green/ ) {print "# My mod : " $0 } else {print $0} }'
OR
awk '{print ($0~/red|green/) ? "# My mod : $0 " : "" $0}'
Which is the shortest amt of code I can think of to achieve the result you are looking for.
awk '{ print (/red|green/ ? "# My mod : " : "") $0 }' file
I want to match every empty line, and when it is an empty line, i want to go to the next line.
The problem is when i type
/^$/ { next }
it always gives me a syntaxt error. It always refers to the first '{'. I thought this was the correct syntax. Can anyone help me please?
My script:
BEGIN{
FS=" "
matching=0
num=0
}
{
/^$/ { next }
if(matching==1 && num>=NF){
print("")
matching=0
}
if(match($NF,type)>0){
for(i=1;i<=NF;i++){
printf($i)
}
printf("\n")
num=NF
matching=1
next
}
if(matching==1){
for(i=1;i<=NF-num;i++){
printf(" ")
}
printf($NF)
printf("\n")
}
}
END{
}
This is my script
You are trying to use the pattern {action} syntax from within an {action} block there.
You need to move your /^$/ {next} line outside of the action block you are starting on line 6 (by moving it above that opening { to get what you want. Or use the if style matching in the action block.
Your script:
BEGIN{
FS=" "
matching=0
num=0
}
{ # <---- This starts an action block.
/^$/ { next } # <----- This is a pattern/action pair.
if(matching==1 && num>=NF){
print("")
matching=0
}
if(match($NF,type)>0){
for(i=1;i<=NF;i++){
printf($i)
}
printf("\n")
num=NF
matching=1
next
}
if(matching==1){
for(i=1;i<=NF-num;i++){
printf(" ")
}
printf($NF)
printf("\n")
}
}
END {
}
Your script has several issues, commented below:
BEGIN{
FS=" "
matching=0 # No need to init variables to zero, this is default behavior.
num=0 # Ditto.
}
{
/^$/ { next } # You can't just use "condition { action }" when you're already
# inside an awk action block. Move this outside of the action
# block or change it to "if (/^$/) { next }"
if(matching==1 && num>=NF){
print("") # print is a builtin not a function. Just do print "".
matching=0
}
if(match($NF,type)>0){
for(i=1;i<=NF;i++){
printf($i) # printf is a builtin, not a function and NEVER put input data
# where the printf formatting string should be. Change this to
# printf "%s", $i
}
printf("\n") # print ""
num=NF
matching=1
next
}
if(matching==1){
for(i=1;i<=NF-num;i++){
printf(" ") # printf " "
}
printf($NF) # printf "%s", $NF
printf("\n") # print ""
}
}
END{ # unused and unnecessary, remove this section.
}
I suspect if you posted some sample input and expected output we could help you write a better (more concise and more idomatic) script.
I want to sum the values of a column but I want to reset the average every 112 lines
what is wrong with this program
BEGIN{ sum=0;i=0}
{ sum=sum+$4
i=i+1
print i
if (i==112)
print "total " sum*8 " average " (sum/i)*8
sum=0
i=0
}
END{}
The output is always 1
awk '{
sum+=$4
}
NR%112==0
{
a=sum*8;
print a,a/112;
sum=0;
}' your_file
I forgot the braces
BEGIN{ sum=0;i=0}
{ sum=sum+$4
i=i+1
print i
if (i==112)
{print "total " sum*8 " average " (sum/i)*8
sum=0
i=0
}
}
END{}
Thank you
You can shorten it some:
awk '
{ sum+=$4
i+=1
print i
if (i==112)
{print "total " sum*8 " average " (sum/i)*8
sum=i=0
}
}' file
You may also use NR instead of i
awk '
{ sum+=$4
print NR%112
if (NR%112==0)
{print "total " sum*8 " average " (sum/112)*8
sum=0
}
}' file
I see that with this it prints 0 instead of line number 112 but that could be fixed if needed.
I am having a issue in having the output of the grep (used in system() in nawk ) assigned to a variable .
nawk '{
CITIZEN_COUNTRY_NAME = "INDIA"
CITIZENSHIP_CODE=system("grep "CITIZEN_COUNTRY_NAME " /tmp/OFAC/country_codes.config | cut -d # -f1")
}'/tmp/*****
The value IND is displayed in the console but when i give a printf the value of citizenshipcode is 0 - Can you pls help me here
printf("Country Tags|%s|%s\n", CITIZEN_COUNTRY_NAME ,CITIZENSHIP_CODE)
Contents of country_codes.config file
IND#INDIA
IND#INDIB
CAN#CANADA
system returns the exit value of the called command, but the output of the command is not returned to awk (or nawk). To get the output, you want to use getline directly. For example, you might re-write your script:
awk ' {
file = "/tmp/OFAC/country_codes.config";
CITIZEN_COUNTRY_NAME = "INDIA";
FS = "#";
while( getline < file ) {
if( $0 ~ CITIZEN_COUNTRY_NAME ) {
CITIZENSHIP_CODE = $1;
}
}
close( file );
}'
Pre-load the config file with awk:
nawk '
NR == FNR {
split($0, x, "#")
country_code[x[2]] = x[1]
next
}
{
CITIZEN_COUNTRY_NAME = "INDIA"
if (CITIZEN_COUNTRY_NAME in country_code) {
value = country_code[CITIZEN_COUNTRY_NAME]
} else {
value = "null"
}
print "found " value " for country name " CITIZEN_COUNTRY_NAME
}
' country_codes.config filename
I am writing an awk script that will take the output of grep and nicely format that into an HTML table. The delimiter is the ":" character; the problem I'm running into is that that character can appear in the text as well. So if I just use $1, $2, and $3 for the filename, line number, and comment respectively, I lose anything after the first : in the comment
Is there a way to say $1, $2, and then $3..NR without explicitly looping over the columns and concatenating them together?
Here's the script so far:
`
#!/usr/bin/awk
BEGIN {
FS=":"
print "<html><body>"
print "<table>"
print "<tr><td>File name</td><td>Line number</td><td>Comment</td></tr>"
}
{
print "<tr><td>" $1 "</td><td>" $2 "</td><td>" $3 "</td></tr>"
}
END {
print "</table>"
print "</body></html>"
}`
And some sample input:
./mysql-connector-java-5.0.8/src/com/mysql/jdbc/BlobFromLocator.java:177: // TODO: Make fetch size configurable
./mysql-connector-java-5.0.8/src/com/mysql/jdbc/CallableStatement.java:243: // TODO Auto-generated method stub
./mysql-connector-java-5.0.8/src/com/mysql/jdbc/CallableStatement.java:836: // TODO: Do this with less memory allocation
BEGIN { FS=":"; OFS=":" }
{ name=$1; number=$2; $1=""; $2=""; comment=substr($0,3); }
{ print gensub(/^[^:]*:[^:]*:/,"","g") }