Awk 3rd column if second coulmn matches with a variable - linux

I am new to Awk and linux. I want to print 3rd column if 2nd column matches with a variable.
file.txt
1;XYZ;123
2;ABC;987
3;ZZZ;999
So I want to print 987, After checking if 2nd column is ABC
name="ABC"
awk -F';' '$2==$name { print $3 }' file.txt
But this is not working. Please help. Please note, I want to use AWK only, to understand how this can be achieved using awk.

Do following and it should fly then. In awk variables don't work like shell you have to explicitly mention them by using -v var_name in awk code.
name="ABC"
awk -F';' -v name="$name" '$2==name{ print $3 }' file.txt

Related

bash: awk print with in print

I need to grep some pattern and further i need to print some output within that. Currently I am using the below command which is working fine. But I like to eliminate using multiple pipe and want to use single awk command to achieve the same output. Is there a way to do it using awk?
root#Server1 # cat file
Jenny:Mon,Tue,Wed:Morning
David:Thu,Fri,Sat:Evening
root#Server1 # awk '/Jenny/ {print $0}' file | awk -F ":" '{ print $2 }' | awk -F "," '{ print $1 }'
Mon
I want to get this output using single awk command. Any help?
You can try something like:
awk -F: '/Jenny/ {split($2,a,","); print a[1]}' file
Try this
awk -F'[:,]+' '/Jenny/{print $2}' file.txt
It is using muliple -F value inside the [ ]
The + means one or more since it is treated as a regex.
For this particular job, I find grep to be slightly more robust.
Unless your company has a policy not to hire people named Eve.
(Try it out if you don't understand.)
grep -oP '^[^:]*Jenny[^:]*:\K[^,:]+' file
Or to do a whole-word match:
grep -oP '^[^:]*\bJenny\b[^:]*:\K[^,:]+' file
Or when you are confident that "Jenny" is the full name:
grep -oP '^Jenny:\K[^,:]+' file
Output:
Mon
Explanation:
The stuff up until \K speaks for itself: it selects the line(s) with the desired name.
[^,:]+ captures the day of week (in this case Mon).
\K cuts off everything preceding Mon.
-o cuts off anything following Mon.

How Can I Perform Awk Commands Only On Certain Fields

I have CSV columns that I'm working with:
info,example-string,super-example-string,otherinfo
I would like to get:
example-string super example string
Right now, I'm running the following command:
awk -F ',' '{print $3}' | sed "s/-//g"
But, then I have to paste the lines together to combine $2 and $3.
Is there anyway to do something like this?
awk -F ',' '{print $2" "$3}' | sed "s/-//g"
Except, where the sed command is only performed on $3 and $2 stays in place? I'm just concerned later on if the lines don't match up, the data could be misaligned.
Please note: I need to keep the pipe for the SED command. I just used a simple example but I end up running a lot of commands after that as well.
Try:
$ awk -F, '{gsub(/-/," ",$3); print $2,$3}' file
example-string super example string
How it works
-F,
This tells awk to use a comma as the field separator.
gsub(/-/," ",$3)
This replaces all - in field 3 with spaces.
print $2,$3
This prints fields 2 and 3.
Examples using pipelines
$ echo 'info,example-string,super-example-string,otherinfo' | awk -F, '{gsub(/-/," ",$3); print $2,$3}'
example-string super example string
In a pipeline with sed:
$ echo 'info,example-string,super-example-string,otherinfo' | awk -F, '{gsub(/-/," ",$3); print $2,$3}' | sed 's/string/String/g'
example-String super example String
Though best solution will be either use a single sed or use single awk. Since you have requested to use awk and sed solution so providing this. Also considering your actual data will be same as shown sample Input_file.
awk -F, '{print $2,$3}' Input_file | sed 's/\([^ ]*\)\([^-]*\)-\([^-]*\)-\([^-]*\)/\1 \2 \3 \4/'
Output will be as follows.
example-string super example string

Linux Awk help on code

I need to print the contents of a file, and give a title to each column, leaving enough space to be readable, and then I need to output this into a new file. I followed this tutorial for a good while but I've gotten stuck.
http://www.thegeekstuff.com/2010/01/awk-introduction-tutorial-7-awk-print-examples
This is the example code they use, which would give me exactly what I need to do with mine. But it will not work when I adjust it.
$ awk 'BEGIN {print "Name\tDesignation\tDepartment\tSalary";}
{print $2,"\t",$3,"\t",$4,"\t",$NF;}
END{print "Report Generated\n--------------";
}' employee.txt
This is mine, as unlike the example, I want the whole document printed and don't really want this "report generated" nonsense under it. I tried adding {print;}' to the end after end, and made sure to start a new line and... nothing.
$ awk 'BEGIN {Print "Firstname\tLastname\tPoints";} END > awktest.txt > done
Where have I gone wrong? It keeps giving me the response Source line 2.
To remove the footline, just drop out anything starting from END till the closing ':
awk 'BEGIN {print "Name\tDesignation\tDepartment\tSalary";} {print $2,"\t",$3,"\t",$4,"\t",$NF;}' employee.txt
In your second example, you left out the closing ', and I suspect you put one more ">" than needed:
awk 'BEGIN {print "Firstname\tLastname\tPoints";}' awktest.txt > done
The latter example will however silently ignore everything read from "awktest.txt".
It looks like what you need is just to insert a header line, which can easily be done with sed (as well as awk) or with cat
$ sed '1iFirstname\tLastname\tPoints' file > output.file
or
$ awk 'BEGIN{print "Firstname\tLastname\tPoints"} 1' file > output.file
or
$ cat <(echo -e "Firstname\tLastname\tPoints") file > output.file
It seems you have missed out the actual printing of the columns and a source file, also I read that you don't need any END actions...
awk 'BEGIN {Print "Firstname\tLastname\tPoints";} END > awktest.txt > done`
Should be...
awk 'BEGIN {Print "Firstname\tLastname\tPoints";}{print $1,"\t",$2,"\t",$3;}' source_file.txt > awktest.txt`
Just remember to change the $1,$2,$3 to what columns on the source file you need.
FYI. I'm no expert, just reading the tuts :)
The awk print function is named print, not Print. idk why all the solutions are including ,"\t", in their print statements. You don't want that - you want to set -v OFS='\t' at the start of the script and then just use , between fields. All you want is:
awk -v OFS='\t' '
BEGIN {print "Name", "Designation", "Department", "Salary"}
{print $2, $3, $4, $NF}
}' employee.txt
assuming those are the correct field numbers you want to print from your data. Sample input/output in your question would be extremely useful to help us answer it.

Add/Sub/Mul/Div a constant to a column in a csv file in linux shell scripting

I am trying to modify the contents of a particular column in a csv file by dividing a constant.
For Ex: If the contents are
1000,abc,0,1
2000,cde,2,3 and so on..
I would like to change it to
1,abc,0,1
2,cde,2,3
I went through all the previous solutions in this blog, and i tried this
awk -F\; '{$1=($1/1000)}1' file.csv > tmp.csv && mv tmp.csv file.csv
The above command opens up file.csv , performs $1/1000 and save it to a temporary file and then overwrites to the original file.
The problem i see is, in the final file.csv, The contents displayed are as follows
1
2
3
4 and so on ..
It doesn't copy all the other columns except column 1.
How can i fix this ?
Because your file is comma-separated, you need to specify a comma as the field separator on both input and output:
$ awk -F, '{$1=($1/1000)}1' OFS=, file.csv
1,abc,0,1
2,cde,2,3
-F, tells awk to use a comma as the field separator on input.
OFS=, tells awk to use a comma as the field separator on output.
Changing the file in-place
With a modern GNU awk:
awk -i inplace -F, '{$1=($1/1000)}1' OFS=, file.csv
With BSD/OSX or other non-GNU awk:
awk -F, '{$1=($1/1000)}1' OFS=, file.csv >tmp && mv tmp file.csv
Alternate style
Some stylists prefer OFS to be set before the code:
awk -F, -v OFS=, '{$1=($1/1000)}1' file.csv

writing an awk command to print every line that has at least one field

How can I write an awk command that prints only lines with at least one field
awk '{if (NF>0) print }'
You command works, and prints lines with one or more fields. But awk prints by default, so you can simplify it:
awk 'NF > 0' file.txt

Resources