Linux Awk help on code - linux

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.

Related

Awk 3rd column if second coulmn matches with a variable

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

Extract domain then paste into the same line using sed/awk/grep/perl

I've started my tech adventure not so long ago - as you will feel from question - but now I'm stucked because after almost a whole day thinking and searching I don't know the proper solution for my problem.
Briefly, I got a file with thousand lines which contains email and firstname. The thing is I really need another column just with the domain name itself for example next to the email address. Please take a look at the examples below.
This is how it looks now:
something#nothing.tld|:|george|-|
anything#another.tld|:|thomas|-|
third#address.tld|:|kelly|-|
How I wanted to look like:
something#nothing.tld|:|nothing.tld|--|george|-|
anything#another.tld|:|another.tld|--|thomas|-|
third#address.tld|:|address.tld|--|kelly|-|
My best guess was using sed to start the process and extract the domain but how can I paste that extracted domain within the same line that's where I stucked.
sed -e 's/.*#\(.*\)|:|*/\1/'
If you could also give a short explanation along with a solution that would be really helpful.
Any help is appreciated.
If you have the following data in a file named, file1,
something#nothing.tld|:|george|-|
anything#another.tld|:|thomas|-|
third#address.tld|:|kelly|-|
you can use : and # as delimiters and add data after it using awk, then save it to a new file,
awk -F '[#:]' '{ print $1"#"$2 ":|" $2"--" $3 }' file1 > file2
Above command saves following data in a file called file2,
something#nothing.tld|:|nothing.tld|--|george|-|
anything#another.tld|:|another.tld|--|thomas|-|
third#address.tld|:|address.tld|--|kelly|-|
With GNU awk for gensub():
$ awk 'BEGIN{FS=OFS="|"} {print $1, $2, gensub(/.*#/,"",1,$1), "--", $3, $4, $5}' file
something#nothing.tld|:|nothing.tld|--|george|-|
anything#another.tld|:|another.tld|--|thomas|-|
third#address.tld|:|address.tld|--|kelly|-|
With any awk:
$ awk 'BEGIN{FS=OFS="|"} {d=$1; sub(/.*#/,"",d); print $1, $2, d, "--", $3, $4, $5}' file
something#nothing.tld|:|nothing.tld|--|george|-|
anything#another.tld|:|another.tld|--|thomas|-|
third#address.tld|:|address.tld|--|kelly|-|
You can do it like this with sed:
sed -E 's/#([^|]+)\|:\|/&\1|--|/' infile
Note the use of a negated-group ([^|]), i.e. match anything except this character group.
Output:
something#nothing.tld|:|nothing.tld|--|george|-|
anything#another.tld|:|another.tld|--|thomas|-|
third#address.tld|:|address.tld|--|kelly|-|

variable assignment is not working in rhel6 linux

file1
ABY37499|ANK37528|DEL37508|SRILANKA|195203230000|445500759
ARJU7499|CHA38008|DEL37508|SRILANKA|195203230000|445500759
IB1704174|ANK37528|DEL37508|SRILANKA|195203230000|445500759
IB1704174|CHA38008|DEL37508|SRILANKA|195203230000|445500759
ABY37500|ANK37529|DEL37509|BRAZIL|195203240000|445500757
ARJU7500|CHA38009|DEL37509|BRAZIL|195203240000|445500757
IB1704175|ANK37529|DEL37509|BRAZIL|195203240000|445500757
i want to convert the fifth column date to another format script below
#!/bin/sh
dt="%Y-%m-%d %H:%M"
awk -F '|' '{print $5}' file1 | sed 's/.\{8\}/& /g'> f1.txt
aa=`(date -f f1.txt +"$dt")`
echo "$aa"
awk -F '|' '$5=$aa' file1
echo "$aa" got desired output but i cannot assign $aa to $5 please help me.
Thanks
I corrected my answer after the commento of Etan Reisner
from AWK man:
The input is read in units called records, and processed by the rules
of your program one record at a time. By default, each record is one
line. Each record is automatically split into chunks called fields.
This makes it more convenient for programs to work on the parts of a
record.
Fields are stored in variables $1, $2, ...
And
The contents of a field, as seen by awk, can be changed within an awk
program; this changes what awk perceives as the current input record.
see the man page
thus, this expression:
awk -F '|' '$5=$aa' file1
does not have the effect of substitute the fifth column of file1.
You have to write the modified output to a second file.
May be this could help you in sed
echo 195203240000 | sed -n -e "s_\(....\)\(..\)\(..\)\(..\)\(..\)_\1-\2-\3 \4:\5_p"
1952-03-24 00:00
This awk script should do what you want.
It isn't exactly pretty but it works assuming the input format is consistent.
awk '{$5=sprintf("%s-%s-%s %s:%s\n",
substr($5,1,4), substr($5,5,2), substr($5,7,2),
substr($5,9,2), substr($5,11,2))} 7' file1 > file1.new
It assigns the new value for the field to $5 and then uses 7 (as a truth-y value) to get the default awk {print} action to print the modified line.

cat passwd | awk -F':' '{printf $1}' Is this command correct?

I'd like to know how cat passwd | awk -F':' '{printf $1}' works. cat /etc/passwd is a list of users with ID and folders from root to the current user (I don't know if it has something to do with cat passwd). -F is some kind of input file and {printf $1} is printing the first column. That's what I've search so far but seems confusing to me.
Can anyone help me or explain to me if it's right or wrong, please?
This is equivalent to awk -F: '{print $1}' passwd. The cat command is superfluous as all it does is read a file.
The -F option determines the field separator for awk. The quotes around the colon are also superfluous since colon is not special to the shell in this context. The print invocation tells awk to print the first field using $1. You are not passing a format string, so you probably mean print instead of printf.

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