gnu cut remove everything from : - cut

I am trying to clean up a set of ipv6 ip addresses.
cat /tmp/ipaddress.txt | /bin/grep -i "unexpectedly shrunk window" | /bin/cut -d' ' -f3 | /bin/cut -d'/' -f1 | /bin/cut -d' ' -f3 | /bin/sort --uniq > /var/log/dos_ip6.txt
/tmp/ipaddress.txt contains the following
TCP: Peer 0000:0000:0000:0000:0000:ffff:4df6:3e12:12345/80 unexpectedly shrunk window 1550831482:1550831483 (repaired)
/var/log/dos_ip6.txt contains the following
0000:0000:0000:0000:0000:ffff:4df6:3e12:12345
i would like to cut the last "*:12345" out.
How can i do this

If your thinking of using two or more cut commands, perhaps consider using awk:
awk 'BEGIN { IGNORECASE=1 } { print gensub(/(.*):.*/, "\\1", "g", $3) | "sort -u" }' /tmp/ipaddress.txt
Result:
0000:0000:0000:0000:0000:ffff:4df6:3e12
Otherwise, a simple pipe to sed should suffice:
... | sed 's/\(.*\):.*/\1/'

I know this is a very old post, but if we want to do this using cut alone, we can do something like this:
echo "TCP: Peer 0000:0000:0000:0000:0000:ffff:4df6:3e12:12345/80 unexpectedly shrunk window 1550831482:1550831483 (repaired)"| cut -d" " -f3| cut -d":" -f1-8
This will result in:
0000:0000:0000:0000:0000:ffff:4df6:3e12

Related

Output of awk in color

I am trying to set up polybar on my newly-installed Arch system. I know very little bash scripting. I am just getting started. If this is not an appropriate question for this forum, I will gladly delete it. I want to get the following awk output in color:
sensors | grep "Package id 0:" | tr -d '+' | awk '{print $4}'"
I know how to do this with echo, so I tried to pass the output so that with the echo command, it would be rendered in color:
sensors | grep "Package id 0:" | tr -d '+' | awk '{print $4}' | echo -e "\e[1;32m ???? \033[0m"
where I want to put the appropriate information where the ??? are.
The awk output is just a temperature, something like this: 50.0°C.
edit: It turns out that there is a very easy way to pass colors to outputs of bash scripts (even python scripts too) in polybar. But I am still stumped as to why the solutions suggested here in the answers work in the terminal but not in the polybar modules. I have several custom modules that use scripts with no problems.
Using awk
$ sensors | awk '/Package id 0:/{gsub(/+/,""); print "\033[32m"$4"\033[0m"}'
If that does not work, you can try this approach;
$ sensors | awk -v color="$(tput setaf 2)" -v end="$(tput sgr0)" '/Package id 0:/{gsub(/+/,""); print color $4 end}'
This is where you want to capture the output of awk. Since awk can do what grep and tr do, I've integrated the pipeline into one awk invocation:
temp=$(sensors | awk '/Package id 0:/ {gsub(/\+/, ""); print $4}')
echo -e "\e[1;32m $temp \033[0m"

Is using awk at least 'awk -F' always will be fine?

What is the difference on Ubuntu between awk and awk -F? For example to display the frequency of the cpu core 0 we use the command
cat /proc/cpuinfo | grep -i "^ cpu MHz" | awk -F ":" '{print $ 2}' | head -1
But why it uses awk -F? We could put awk without the -F and it would work of course (already tested).
Because without -F , we couldn't find from wath separator i will begin the calculation and print the right result. It's like a way to specify the kind of separator for this awk's using. Without it, it will choose the trivial separator in the line like if i type on the terminal: ps | grep xeyes | awk '{print $1}' ; in this case it will choose the space ' ' as a separator to print the first value: pid OF the process xeyes. I found it in https://www.shellunix.com/awk.html. Thanks for all.

Makefile variable not set from grep output

I am trying to set the variable COGLINE to be the output of my grep line (which is searching my config.json file for the regExthe "cogs"). When I execute the grep line it correctly outputs the proper line number, but when I echo the variable it comes up blank.
COGLINE = $(grep -n \"cogs\" ~/Desktop/Repos/pronghorn/config.json | cut -f1 -d:)
all:
grep -n \"cogs\" ~/Desktop/Repos/pronghorn/config.json | cut -f1 -d:
echo $(COGLINE)
Here is the output:
GlennMBP:test glenn$ make all
grep -n \"cogs\" ~/Desktop/Repos/pronghorn/config.json | cut -f1 -d:
2
echo
You can see that the line number is properly found as "2", but the variable comes up blank as if it were not set. What am I doing wrong?
grep is not a make function. That COGLINE = line is a make assignment.
You either need to use
COGLINE := $(shell grep -n \"cogs\" ~/Desktop/Repos/pronghorn/config.json | cut -f1 -d:)
if you want that run at make parse time and want it in a make variable.
Or
all:
COGLINE=$$(grep -n \"cogs\" ~/Desktop/Repos/pronghorn/config.json | cut -f1 -d:); \
echo "$${COGLINE}"
to run it at all recipe execution time and have it in a shell variable.
There are middle grounds as well but those are the two basic ideas.

Convert bash line to use in perl

How would I go about converting the following bash line into perl? Could I run the system() command, or is there a better way? I'm looking for perl to print out access per day from my apache access_log file.
In bash:
awk '{print $4}' /etc/httpd/logs/access_log | cut -d: -f1 | uniq -c
Prints the following:
632 [27/Apr/2014
156 [28/Apr/2014
awk '{print $4}' /etc/httpd/logs/access_log | cut -d: -f1 | uniq -c
perl -lane'
($val) = split /:/, $F[3]; # First colon-separated elem of the 4th field
++$c{$val}; # Increment number of occurrences of val
END { print for map { "$c{$_} $_" } keys %c } # Print results in no order
' access.log
Switches:
-l automatically appends a newline to the print statement.
-l also removes the newlines from lines read by -n (and -p).
-a splits the line on whitespace into the array #F.
-n loops over the lines of the input but does not print each line.
-e execute the given script body.
Your original command translated to a Perl one-liner:
perl -lane '($k) = $F[3] =~ /^(.*?):/; $h{$k}++ }{ print "$h{$_}\t$_" for keys %h' /etc/httpd/logs/access_log
You can change all your commands to one from:
awk '{print $4}' /etc/httpd/logs/access_log | cut -d: -f1 | uniq -c
to
awk '{split($4,a,":");b[a[1]]++} END {for (i in b) print b[i],i}' /etc/httpd/logs/access_log

Why does (g)awk reverse these lines of output?

So, I'm seeing this output and I'm a bit surprised:
$ echo "a,b,c,d,e,f,g" | cut -d, -f-4
a,b,c,d
$ echo "a,b,c,d,e,f,g" | cut -d, -f6-
f,g
echo "a,b,c,d,e,f,g" | awk '{ print $0 | "cut -d, -f-4"; print $0 | "cut -d, -f6-"; }'
f,g
a,b,c,d
(As a side note, I realize this is a completely silly thing to do in awk, but it's the only command I've seen it happen for!).
As I understand it, this should pipe the record into the two commands -- in order. But for some reason, the output appears reversed. If I do this instead
$ echo "a,b,c,d,e,f,g" | awk '{ print $0 | "echo hello"; print $0 | "echo goodbye"; }'
hello
goodbye
then everything comes in the order I expected. I'm thinking this must be some sort of race condition, but I'm surprised that awk doesn't wait for the subcommand in the pipe to finish. Is this a known issue of using awk or something pecular to gawk? Is there any way to avoid such a pitfall?
EDIT:
I tried it using mawk too... same (reversed) result, and seems to happen consistently for both.
In order to ensure that an external command is completed, you must close the command.
$ echo "a,b,c,d,e,f,g" | awk 'BEGIN {cmd1 = "cut -d, -f-4"; cmd2 = "cut -d, -f6-"} { print $0 | cmd1; close(cmd1); print $0 | cmd2; close(cmd2)}'
a,b,c,d
f,g
I am surprised by this but it's clear that awk runs commands in parallel. Try this:
# time echo "a,b,c,d,e,f,g" | awk '{ print $0 | "sleep 2"; print $0 | "sleep 2"; }'
real 0m2.250s
user 0m0.030s
sys 0m0.060s