how to pipe into awk script - bash

I have this awk script:
#!/usr/bin/awk -f
BEGIN {IGNORECASE=1}
/nVidia/ {inner=1;pci=$1}
/(corr|fatal)err\-/ {if (inner) print pci, $1, $2, $3, $4, $5, $6, $7}
$0=="" {inner=0}
is there a syntax to always pipe sudo lspci -vvv to this script? I'm having to type sudo lspci -vvv|./checkpci each time I run the script. I know I could create a second script to launch the first script, but I think that is messy and would like to know the proper way to do so.
as an aside, I'm having some issues with my graphics card crashing and have seen the UncorrErr flag on some of the devices, does anyone have a reference as to what this means or how to troubleshoot further? right now I'm just going to run this script periodically to see when the errors show up in lspci to see if there is a time correlation.

This should work for you:
#!/usr/bin/awk -f
BEGIN {
IGNORECASE = 1
cmd = "sudo lspci -vvv"
while ((cmd | getline) > 0) {
if ($0 ~ /nVidia/) {inner = 1; pci = $1}
if ($0 ~ /(corr|fatal)err\-/) {if (inner) print pci, $1, $2, $3, $4, $5, $6, $7}
if ($0 == "") {inner = 0}
}
close(cmd)
}

I would change your awk script into a shell script:
#!/bin/sh
sudo lspci -vvv | /usr/bin/awk '
BEGIN {IGNORECASE=1}
/nVidia/ {inner=1;pci=$1}
/(corr|fatal)err\-/ {if (inner) print pci, $1, $2, $3, $4, $5, $6, $7}
$0=="" {inner=0}
'

Related

Print a column in awk if it matches, if not then still print the line (without that column)

I'm trying to do some filtering with awk but I'm currently running into an issue. I can make awk match a regex and print the line with the column but I cannot make it print the line without the column.
awk -v OFS='\t' '$6 ~ /^07/ {print $3, $4, $5, $6}' file
Is currently what I have. Can I make awk print the line without the sixth column if it doesn't match the regex?
Set $6 to the empty string if the regex doesn't match. As simple as that. This should do it:
awk -v OFS='\t' '{ if ($6 ~ /^07/) { print $3, $4, $5, $6 } else { $6 = ""; print $0; } }' file
Note that $0 is the entire line, including $2 (which you didn't seem to use). It will print every column except the 6th column.
If you just want to print $3, $4 and $5 when there isn't a match, use this instead:
awk -v OFS='\t' '{ if ($6 ~ /^07/) print $3, $4, $5, $6; else print $3, $4, $5 }' file

bash- replace empty field with . in piped statement

I'm looping over a list of files, while for each file im scanning for specific things to grep out.
# create .fus file
grep DIF $file | awk '{
if ( $7 != $13 )
print $4, "\t", $5, "\t", $20, "\t", $10, "\t", $11, "\t", $22, "\t", "Null";
}' > $file_name.fus
# create .inv_fus file
grep DIF $file | awk '{
if ( $7 == $13 )
print $4, "\t", $5, "\t", $20, "\t", $10, "\t", $11, "\t", $22, "\t", "Null";
}' > $file_name.inv_fus
# create .del file
echo -e '1\t1\t1\t1' > ${file_name}.del
echo -e '1\t1\t1\t3' >> ${file_name}.del
grep DEL ${file} | awk '{print $4, "\t", $5, "\t", $12, "\t", "2"}' >> ${file_name}.del
The first awk checks if the values of column 7 and 13 are different, if they are, write to file.
The second awk checks if hte values are the same, if they are, write to file. The third creates a file with 2 lines always the same, and the rest filled in by lines containing 'DEL'.
The output files I use to generate a plot, but this fails because some fields are empty. How can I change my code (I guess the awk statement ?) so that it checks for empty fields (for columns 4, 5, 20, 10, 11 and 22) and replace empty columns with dots '.' ?
Like the other response has said, there's a lot of simplification that could happen here, but without knowing input or expected output its hard to comment on what changes would be beneficial.
Regardless, the question seems to boil down to replacing empty fields with dots in your output for some process down the line. Adding a function like this to your awk scripts would seem to do the trick:
function clean() {
for(i = 1; i <= NF; i++) { if($i==""){$i="."}; }
}
For example, given this input in test.txt:
a1,a2,a3,a4
b1,,b3,b4
,,c3,
d1,d2,d3,
Running the following awk results in empty fields being periods.
awk -F',' 'function clean() {
for(i = 1; i <= NF; i++) { if($i==""){$i="."}; }
}
BEGIN {OFS=","}
{clean(); print;}' test.txt
Example output:
a1,a2,a3,a4
b1,.,b3,b4
.,.,c3,.
d1,d2,d3,.
Let's start by cleaning up your script. Replace the whole thing with just one simple awk command:
awk -v file_name="$file_name" '
BEGIN {OFS="\t"; print 1, 1, 1, 1 ORS 1, 1, 1, 3 > (file_name ".del")}
/DIF/ {print $4, $5, $20, $10, $11, $22, "Null" > (file_name "." ($7==$13?"inv_":"") "fus")}
/DEL/ {print $4, $5, $12, 2 > (file_name ".del")}
' "$file"
Now, update your question with sample input and expected output that captures what else you need it to do.

Awk input and output file delimiter

I try to parse a column delimited password file using awk and put hostname in the beginning and add some fields. I need a comma separated output. So what I try is:
/usr/xpg4/bin/awk -F':' MYHOST=$(hostname) 'BEGIN{OFS=",";} {print MYHOST, $1, $3, $4, $5;}' /etc/passwd
But this command didn't produce output I wanted. This is a Solaris box, regular awk didn't work so I try with /usr/xpg4/bin/awk
this may help you:
/usr/xpg4/bin/awk -F':' -v MYHOST="$(hostname)" 'BEGIN{OFS=","} {print MYHOST, $1, $3, $4, $5;}' /etc/passwd

awk syntax error help identifying

I can't seem to identify where the syntax error is ..I've tried to these 2 statements but nothing gets written to the 'BlockedIPs' file. Can someone please help? Thanks!
awk '/ (TCP|UDP) / { split($5, addr, /:/); cmd = "/Users/user1/Scripts/geoiplookup " addr[1] | awk '{print $4, $5, $6}'; cmd | getline rslt; close(cmd); print $1, $2, $3, rslt }' < "$IP_PARSED" >> "$BlockedIPs"
awk '/ (TCP|UDP) / { split($5, addr, /:/); cmd = "/Users/user1/Scripts/geoiplookup " addr[1] " | awk '{print $4, $5, $6}'" ; cmd | getline rslt; close(cmd); print $1, $2, $3, rslt }' < "$IP_PARSED" >> "$BlockedIPs"
Your problem is primarily with quoting and stems from the fact that you're trying to call AWK from within an AWK one-liner. It's certainly possible, but getting the quoting right would be very tricky.
It would be much better if you retrieved the complete output of geoiplookup into a variable then did a split() to get just the data you need. Something like:
awk '/ (TCP|UDP) / { split($5, addr, /:/); cmd = "/Users/user1/Scripts/geoiplookup " addr[1]; cmd | getline rslt; split(rslt, r); close(cmd); print $1, $2, $3, r[4], r[5], r[6] }' < "$IP_PARSED" >> "$BlockedIPs"

How can I collapse this bash command line into an awk statement?

I've created an awk script and use it like this:
# grep -E "[PM][IP][DO][:S]" file.txt | awk-script
How can I modify the awk script to include the effort of the grep command (which is searching for either "PID:" or "MPOS"?
awk-script is:
#!/usr/bin/awk -f
/Sleeve/ {
printf("%8d, %7d, %7.2f, %7.2f, %7.2f\n", $5, $6, $7, $30, $31)
}
/Ambient/ {
printf("%8d, %7d,,,, %7.2f, %7.2f\n", $5, $6, $7, $8)
}
/MPOS:/ {
printf("%8d, %7d,,,,,, %5d, %5d\n", $4, $5, $2, $3)
}
If you just want to search for PID: or MPOS, you can say that if you don't find them in the line, you want to skip following rules:
#!/usr/bin/awk -f
!/PID:|MPOS/ {
next
}
/Sleeve/ {
printf("%8d, %7d, %7.2f, %7.2f, %7.2f\n", $5, $6, $7, $30, $31)
}
/Ambient/ {
printf("%8d, %7d,,,, %7.2f, %7.2f\n", $5, $6, $7, $8)
}
/MPOS:/ {
printf("%8d, %7d,,,,,, %5d, %5d\n", $4, $5, $2, $3)
}
I tried litb's answer in busybox (on Ubuntu in Bash) and it worked for me. For testing, I used the following shebang to match where I have symbolic links to busybox:
#!/home/username/busybox/awk -f
And ran the test using:
./awk-script file.txt
I also ran the test under busybox sh (with PATH=/home/username/busybox:$PATH although not necessary for this) and it worked there.
When you say "I still have grief." what does that mean? Are you getting error messages or incorrect results?
By the way, unless you're searching for all permutations of the characters, you can do your grep like this:
grep -E "(PID:|MPOS)" file.txt

Resources