Unix awk pass variable as fileName - file

I am using the following command to split one file into two.
currentCouponFile="$DIR/kozo_agency_current_coupon_ts-"$HMD_EFF_DT".csv"
agencySpreadFile="$DIR/kozo_agency_spread_ts-"$HMD_EFF_DT".csv"
awk -F '|' 'BEGIN{OFS=","};{$1=$1; if(NF == 2){print > "$currentCouponFile"}else{ print > "$agencySpreadFile"}}' $fileName
Doing echo on currentCouponFile and agencySpreadFile gives me the desired filename.
However the resultant file get created as $agencySpreadFile and $currentCouponFile. Not the in .csv format.
Any solution ?

Do not use shell variables inside awk.
currentCouponFile="$DIR/kozo_agency_current_coupon_ts-"$HMD_EFF_DT".csv"
agencySpreadFile="$DIR/kozo_agency_spread_ts-"$HMD_EFF_DT".csv"
awk -F '|' -v current="$currentCouponFile" -v agency="$agencySpreadFile" '
BEGIN{OFS=","}
{
$1=$1;
if(NF == 2)
{print > current}
else
{print > agency}
}' $fileName

Related

Putting multiline awk command in a for loop not printing the variable

I have a command as follows, which takes lines from the Allergens file, based on lines from the IDs file.
awk '
FNR==NR{
a[$1]
next
}
/^Query/ || $2 in a
' IDs C100_Allergens | grep -B 1 'Hit: ' | grep -v '^--' > C100_Allergens_matches.txt
However, I have numerous sample_Allergens files, and want to run it in a loop as such, where list is a file with different sample names:
for i in `cat list`
do
awk '
FNR==NR{
a[$1]
next
}
/^Query/ || $2 in a
' IDs "$i"_Allergens | grep -B 1 'Hit: ' | grep -v '^--' > "$i"_Allergens_matches.txt
done
I tried this loop, including using the variable flag for awk, i.e. -v i="$i":
for i in `cat list`
do
awk -v i="$i" '
FNR==NR{
a[$1]
next
}
/^Query/ || $2 in a
' IDs "$i"_Allergens | grep -B 1 'Hit: ' | grep -v '^--' > "$i"_Allergens_matches.txt
done
I only keep getting empty files. Thanks in advance for your help!

write a shell script with a loop

i have an awk command as below :
awk 'FNR==NR{a[$1$2]=$3;next} ($1$2 in a) {print$1,$2,a[$1$2],$3}' ""each line of file 1"" >./awkfile/12as_132l.txt
and f1.txt content is :
1sas.txt 12ds.txt
13sa.txt 21sa.txt
i want that my script read each line of fil1.txt and put the contents in this awk command...instead of """each line of file1"".. and execute the command like below:
awk 'FNR==NR{a[$1$2]=$3;next} ($1$2 in a) {print$1,$2,a[$1$2],$3}' 1sas.txt 12ds.txt >./awkfile/12as_132l.txt
awk 'FNR==NR{a[$1$2]=$3;next} ($1$2 in a) {print$1,$2,a[$1$2],$3}' 13sa.txt 21sa.txt >./awkfile/12as_132l.txt
i need a loop but the problem is that's a little strange for me .
Here is Snippet, which reads 2 fields line by line from f1.txt, put it into variable, and used in awk
#!/usr/bin/env bash
while read -r col1file col2file; do
# your command goes here
# this awk does nothing, replace it with your command
awk '{ }' "$col1file" "$col2file" > someoutfile
done < "f1.txt"
Test Results:
akshay#db-3325:/tmp$ cat f1.txt
1sas.txt 12ds.txt
13sa.txt 21sa.txt
akshay#db-3325:/tmp$ cat test.sh
while read -r col1file col2file; do
echo "col1 : $col1file"
echo "col2 : $col2file"
# your command goes here
# this awk does nothing, replace it with your command
# awk '{ }' "$col1file" "$col2file" > someoutfile
done < "f1.txt"
akshay#db-3325:/tmp$ bash test.sh
col1 : 1sas.txt
col2 : 12ds.txt
col1 : 13sa.txt
col2 : 21sa.txt
change the IFS to IFS=' ' and use loop .

Loop over a single column condition statement in awk

I want to print a line if a statement is true, but I want to loop through several variations. This is works as a batch script:
Awk "($9==1) {print $0}" file > out.txt & type out.txt >> all_out.txt
Awk "($9==3) {print $0}" file > out.txt & type out.txt >> all_out.txt
Awk "($9==5) {print $0}" file > out.txt & type out.txt >> all_out.txt
But not very elegant. Can this be written into a for loop or if statement? I'm using gnuawk on windows with cygwin installed.
Any help would be greatly appreciated.
try:
awk '($9==1) || ($9==3) || ($9==5)' Input_file > all_out.txt
OR
awk '($9%2 != 0)' Input_file > all_out.txt
Considering that you want to take all conditions output into a single file here, let me know if this is not the case.
Try this -
$ awk '($9 ~ /^1$|^3$|^5$/) {print $0}' file

working with arrays in bash and do stuff

I am writing a bash script and need help. This is what I tried:
With the help of #merlin2011
#!/bin/bash
if [ $# -ne 2 ]; then
echo "Usage: `basename $0` <absolute-path> <number>"
exit 1
fi
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
#find . -name "$2" -exec mv {} /some/path/here \;
find $1 >> /tmp/test
for line in $(cat `/tmp/test`); do
echo $line | mv $2 awk -F"/" '{for (i = 1; i < NF; i++) if ($i == "$2") print $(i-1)}'
done
Now I want to check the result of find command from array and then if there were a directory named 2010 then get the absolute path of it. For ecxample:
arr[1]="/path/to/2010/file.db"
Then I want to rename 2010 to parent directory to. My pattern is:
arr[1]="/path/to/2010/file.db"
arr[2]="/path/test/2010/fileee.db"
arr[3]="/path/tt/2010/fileeeee.db"
.
.
.
arr[100]="/path/last/2010/fileeeeeee.db"
Result should be:
mv /path/to/2010/ to
mv /path/test/2010 test
mv /path/tt/2010/ tt
.
.
.
mv /path/last/2010 last
UPDATE:
Totally I want to know how to get a variable inversely in awk...
/path/to/dir1/2010/file.db
I want to search in absolute path then find 2010 and rename it in previous path with / pattern like : awk -F"/" {print [what?]}
tell awk my state is 2010 then print one variable before it by knowing splitter is /
UPDATE
The files dirs and subdirs pattern are:
/path/to/file/efsef/2010/1.db
/path/to/file/hfjh/sdfsf/2010/2.db
/path/to/file/dsf/sdhher/aqwe/sfrt/2010/3.db
.
.
.
/path/to/file/kldf/2010/100.db
I want to rename all 2010 dirs to their parent then tar all .db
This is what exactly I want :)
This answer addresses only the OP's update. My best interpretation is that you are trying to get awk to print the value dir1 inside the string /path/to/dir1/2010/file.db. The following line will achieve it.
awk -F"/" '{for (i = 1; i < NF; i++) if ($i == "2010") print $(i-1)}'
I tested using the following command, which will output dir1.
echo /path/to/dir1/2010/file.db | awk -F"/" '{for (i = 1; i < NF; i++) if ($i == "2010") print $(i-1)}'
Based on your update, you should surround the awk command with the backtic operator.
mv $2 `awk -F"/" '{for (i = 1; i < NF; i++) if ($i == "$2") print $(i-1)}'`
To implement, we have to do the recursive folder search.
It should be combination of two commands like find and mv
find . -name "2010" -exec mv {} /some/path/here \;
Other way shared by merlin2011
mv $2 awk -F"/" `'{for (i = 1; i < NF; i++) if ($i == "$2") print $(i-1)}'`
Here is awk command:
awk -F"/$2/" '{split($1, a, "/"); system("echo mv " $0 " " a[length(a)]);}' <<< "$1"
mv /path/to/dir1/2010/file.db dir1
Once you're satisfied remove echo in system command.

How to pass bash parameter to awk script?

I have awk file:
#!/bin/awk -f
BEGIN {
}
{
filetime[$'$colnumber']++;
}
END {
for (i in filetime) {
print filetime[i],i;
}
}
And bash script:
#!/bin/bash
var1=$1
awk -f myawk.awk
When I run:
ls -la | ./countPar.sh 5
I receive error:
ls -la | ./countPar.sh 5
awk: myawk.awk:6: filetime[$'$colnumber']++;
awk: myawk.awk:6: ^ invalid char ''' in expression
Why? $colnumber must be replaced with 5, so awk should read 5th column of ls ouput.
Thanks.
You can pass variables to your awk script directly from the command line.
Change this line:
filetime[$'$colnumber']++;
To:
filetime[colnumber]++;
And run:
ls -al | awk -f ./myawk.awk -v colnumber=5
If you really want to use a bash wrapper:
#!/bin/bash
var1=$1
awk -f myawk.awk colnumber=$var1
(with the same change in your script as above.)
If you want to use environment variables use:
#!/bin/bash
export var1=$1
awk -f myawk.awk
and:
filetime[ENVIRON["var1"]]++;
(I really don't understand what the purpose of your awk script is though. The last part could be simplified to:
END { print filetime[colnumber],colnumber; }
and parsing the output of ls is generally a bad idea.)
The easiest way to do it:
#!/bin/bash
var=$1
awk -v colnumber="${var}" -f /your/script
But within your awk script, you don't need the $ in front of colnumber.
HTH
Passing 3 variable to script myscript.sh
var1 is the column number on which condition has set.
While var2 & var3 are input and temp file.
#!/bin/ksh
var1=$1
var2=$2
var3=$3
awk -v col="${var1}" -f awkscript.awk ${var2} > $var3
mv ${var3} ${var2}
execute it like below -
./myscript.sh 2 file.txt temp.txt

Resources