Why my awk string match not working? - unix

$ echo foooobazbarrrrr |
> gawk 'match($0, /(fo+).+(bar*)/, arr)
> {print arr[1], arr[2] }'
The output of this code should be foooo barrrr but on my Ubuntu, it is not working and failed.
If I wrote this code
> gawk 'match($0, /(fo+).+(bar*)/)
> {print }'
Then its working. Why is the first version not working?

Your command is slightly different from the example in the GNU manual. It has the opening { at the very start so that there's no pattern to match and the newline is required to separate the two awk commmands.
$ echo foooobazbarrrrr | gawk '{ match($0, /(fo+).+(bar*)/, arr)
> print arr[1], arr[2] }'
foooo barrrrr
Alternatively, you could use a semi-colon instead of a newline to separate the commands:
$ echo foooobazbarrrrr | gawk '{ match($0, /(fo+).+(bar*)/, arr); print arr[1], arr[2] }'
foooo barrrrr
Your version of the command will work if it’s entered as one line:
$ echo foooobazbarrrrr | gawk 'match($0, /(fo+).+(bar*)/, arr) {print arr[1], arr[2] }'
foooo barrrrr

Related

awk change shell variable

I would like to modify several shell variables within awk:
echo "$LINE_IN" | awk '/pattern1/ {print $0; WRITTEN=1; REC=$REC+1}' >> $FILE1
I tried to put eval, but still does not work:
eval $( echo "$LINE_IN" | awk '/pattern1/ {print $0; WRITTEN=1; REC=$REC+1}' >> $FILE1 )
Any suggestion?
I would like to use k-shell script, thanks!
Count the hits when you are finished:
echo "${LINE_IN}" | grep -E 'pattern1' > "${FILE1}"
REC=$(wc -l < "${FILE1}")
if (( REC > 0 )); then
WRITTEN=1
fi
When you really want to use awk, you must let awk write the results to stdout and parse stdout:
echo "${LINE_IN}" | awk '/echo/ {print $0 > "x3"; WRITTEN=1; REC++}
END { print "WRITTEN=" WRITTEN; print "REC=" REC}'
WRITTEN=1
REC=6
And when you want the variables really set, wrap it:
source (echo "${LINE_IN}" | awk '/echo/ {print $0 > "x3"; WRITTEN=1; REC++}
END { print "WRITTEN=" WRITTEN; print "REC=" REC}')
Note: Get used to using lowercase variable names like written, file and rec.

Remove all the hash out value of teradata in unix

Can anyone help me on this
I have one variable which contain
var="DDP_COMPLIANCE ,ONT_COMPLIANCE_CD --,TECHNICIAN_EMPLOYEE_ID --,ENTRY_OPERATOR_EMPLOYEE_ID --,LAST_UPDATE_OPERATOR_EMPLOYEE_ID ,PARENT_TROUBLE_CALL_WORK_ORDER_ID --,abc_line ,PARENT_INSTALL_WORK_ORDER_ID ,TECH_COMPLIANCE_STARTBY_TS "
i want to remove all the "--,columnname" and print rest
and the output will be
DDP_COMPLIANCE ,ONT_COMPLIANCE_CD,PARENT_TROUBLE_CALL_WORK_ORDER_ID ,PARENT_INSTALL_WORK_ORDER_ID ,TECH_COMPLIANCE_STARTBY_TS
i am using Sed command as
echo $var | sed 's/--.*,/,/'
but got output as
DDP_COMPLIANCE ,ONTRAC_COMPLIANCE_CD ,TECH_COMPLIANCE_STARTBY_TS
which is incorrect
I'm sure there's a simple way, but for time being, this works for you?
echo $var | awk '{ for (i=1; i<=NF; i++) print $i }' | grep -v "^--" | awk 'BEGIN { ORS=" " }; { print $0 }'
the last awk part was to format the result back in a single line.
Result:
$ echo $var | awk '{ for (i=1; i<=NF; i++) print $i }' | grep -v "^--" | awk 'BEGIN { ORS=" " }; { print $0 }'
DDP_COMPLIANCE ,ONT_COMPLIANCE_CD ,PARENT_TROUBLE_CALL_WORK_ORDER_ID ,PARENT_INSTALL_WORK_ORDER_ID ,TECH_COMPLIANCE_STARTBY_TS

BASH SHELL print columns with specific order

I have this file :
933|Mahinda|Perera|male|1989-12-03|2010-03-17T13:32:10.447+0000|192.248.2.123|Firefox
1129|Carmen|Lepland|female|1984-02-18|2010-02-28T04:39:58.781+0000|81.25.252.111|Internet Explorer
4194|Hồ Chí|Do|male|1988-10-14|2010-03-17T22:46:17.657+0000|103.10.89.118|Internet Explorer
8333|Chen|Wang|female|1980-02-02|2010-03-15T10:21:43.365+0000|1.4.16.148|Internet Explorer
8698|Chen|Liu|female|1982-05-29|2010-02-21T08:44:41.479+0000|14.103.81.196|Firefox
8853|Albin|Monteno|male|1986-04-09|2010-03-19T21:52:36.860+0000|178.209.14.40|Internet Explorer
10027|Ning|Chen|female|1982-12-08|2010-02-22T17:59:59.221+0000|1.2.9.86|Firefox
and with this order
./tool.sh --browsers -f <file>
i want to count the number of the browsers in specific order , for example :
Chrome 143
Firefox 251
Internet Explorer 67
i use this command :
if [ "$1" == "--browsers" -a "$2" == "-f" -a "$4" == "" ]
then
awk -F'|' '{print $8}' $3 | sort | uniq -c | awk ' {print $2 , $3 , $1} '
fi
but it works only for 3 arguments. How to make it work for many arguments? for example a browser with 4 words or more
Seems like an awk one-liner to count your browsers:
$ awk -F'|' '{a[$8]++} END{for(i in a){printf("%s %d\n",i,a[i])}}' inputfile
Firefox 3
Internet Explorer 4
This increments elements of an array, then at the end of the file steps through the array and prints the totals. If you want the output sorted, you can just pipe it through sort. I don't see a problem with multiple words in a browser name.
try this:
awk -F"|" '{print $8}' in | sort | uniq -c | awk '{print $2,$1}'
where in is the input file.
output
[myShell] ➤ awk -F"|" '{print $8}' in | sort | uniq -c | awk '{print $2,$1}'
Firefox 3
Internet 4
also for parsing argument is better to use getopts
i.e.
#!/bin/bash
function usage {
echo "usage: ..."
}
while getopts b:o:h opt; do
case $opt in
b)
fileName=$OPTARG
echo "filename[$fileName]"
awk -F"|" '{print $8}' $fileName | sort | uniq -c | awk '{print $2,$1}'
;;
o)
otherargs=$OPTARG
echo "otherargs[$otherargs]"
;;
h)
usage && exit 0
;;
?)
usage && exit 2
;;
esac
done
output
[myShell] ➤ ./arg -b in
filename[in]
Firefox 3
Internet 4
Your final Awk hard-codes two fields; just continue with $4, $5, $6 etc to print more fields. However, this will add a spurious space for each comma.
Better yet, since the first field is fixed width (because that's the output format from uniq -c), you can do print substr($0,8), $1
I'd do it in perl:
#!/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %count_of;
while ( <> ) {
chomp;
$count_of{(split /\|/)[7]}++;
}
print Dumper \%count_of;
This can be cut down to a one liner:
perl -F'\|' -lane '$c{$F[7]++}; END{ print "$_ => $c{$_}" for keys %c }'

Not getting expected file result using awk

#!/bin/bash
delete_file () {
for file in processor_list.txt currnet_username.txt unique_username.txt
do
if [ -e $file ] ;then
rm $file
fi
done
}
delete_file
ps -elf > processor_list.txt ; chmod 755 processor_list.txt
awk '{print $3}' processor_list.txt > currnet_username.txt ; chmod 755 currnet_username.txt
sort -u currnet_username.txt > unique_username.txt ;chmod 755 unique_username.txt
while read line ; do
if [ -e $line.txt ] ;then
rm $line.txt
fi
grep $line processor_list.txt >$line.sh ;chmod 755 $line.sh
awk '{if($4 == "$line") print $0;}' $line.sh > ${line}1.txt ; #mv ${line}1.txt $line.txt;chmod 755 $line.txt
done < unique_username.txt
I'm a beginner of unix shell scripting. please suggested, i am not getting expected results in ${line}1.txt.
For example, I have two UID like kplus , kplustp. what is my requirement is find "kplus" string from ps -elf command and create a file as same name like kplus.txt and redirect or move the data whatever found data using grep command.
But I am getting kplus and kplustp data in kplus.txt file. I need only kplus value based on UID column from ps –elf in kplus.txt file.
This is wrong way to read variable using awk
awk '{if($4 == "$line") print $0;}' $line.sh
Use:
awk '{if($4 == var) print $0;}' var="$line" $line.sh
Or shorten to
awk '$4==var' var="$line" $line.sh
default action is {print $0} if no action is specified.
If you need to search for the text $line escape the $ in regex
awk '$4==/\$line/' $line.sh
or in text it should work directly
awk '$4=="$line"' $line.sh

how to get NF from AWK argument?

I've been trying to get the NF from 2 arguments (not files) in awk without success .
This is the command line:
awk -f the_program 12/12/2013 11/11/2014
Is it possible to some how pipe ARGV[1] or ARGV[2] to getline to get NF?
I wanted to get NF so I can easily validate the arguments before doing other stuff with them
You can do it in pure awk:
$ awk -F/ 'BEGIN{for (i=1;i<ARGC;i++) {print split(ARGV[i], a) }}' 12/12/2013 11/11/2014
3
3
I am not sure if it can be done alone using awk. Try using wrapper bash script around it.
myscript.sh
#!/bin/bash
awk 'BEGIN {
RS=" "; FS="/";
}
{
print NF;
}' <(echo $*)
Test
% myscript.sh 12/12/2013 11/11/2014
3
3
Or eliminating use of echo with <<< as suggested by #fedorqui
#!/bin/bash
awk 'BEGIN {RS=" ";FS="/";} {print NF}' <<<$*
Is this all you want?
$ awk 'BEGIN{ print ARGC - 1 }' 12/12/2013 11/11/2014
2
If not, post some expected output and explain why.

Resources