Change in format for awk - bash

My line of code is below.
awk 'BEGIN {printf "gnome-terminal"}
{printf " --tab -e \"telnet "$4" "$6 " | tee " $1$12"\" -t \"" $1" "$12 "\"" }
END {printf "\n"}' temp1.prm >> abc
Output gives this in abc:
gnome-terminal --tab -e "telnet 10.31.248.104 3007 | tee dutA1MM1" -t "dutA1 MM1"
I have to get below format:
gnome-terminal --tab -e 'bash -c "telnet 10.31.248.104 3007 | tee script1.log"' -t "dutA1 MM1"
Can anyone help ?

Try this double-quotes quoted format:
awk "BEGIN {printf \"gnome-terminal\"} {printf \" --tab -e 'bash -c \\\"telnet \"\$4\" \"\$6 \" | tee \" \$1\$12\"\\\"' -t \\\"\" \$1\" \"\$12 \"\\\"\" } END { printf \"\\n\"}" temp1.prm >> abc
Testing with echo, the argument to awk would literally be
BEGIN {printf "gnome-terminal"} {printf " --tab -e 'bash -c \"telnet "$4" "$6 " | tee " $1$12"\"' -t \"" $1" "$12 "\"" } END { printf "\n"}

Don't get into a quoting nightmare. You could keep things tidy like so:
BEGIN {
double_quote = "\""
s1 = "gnome-terminal --tab -e 'bash -c "
s2 = double_quote "telnet 10.31.248.104 3007 | tee script1.log" double_quote
s3 = "' -t dutA1 MM1"
printf "%s%s%s\n",s1,s2,s3
}

You probably want something like this:
awk '{ printf "gnome-terminal --tab -e \047bash -c \"telnet %s %s | tee script1.log\"\047 -t \"%s %s\"\n", $4, $6, $1, $12 }' file
but since you didn't provide sample input and expected output it's just a guess.

Related

Bash - Counter for multiple parameters in file

I created a command, which works, but not exactly as I want. So I would like to upgrade this command to right output.
My command:
awk '{print $1}' ios-example.com.access | sort | uniq -c | sort -nr
Output of my command:
8 192.27.69.191
2 82.202.69.253
Input file:
https://pajda.fit.vutbr.cz/ios/ios-19-1-logs/blob/master/ios-example.com.access.log
Output I need(hashtags instead of numbers):
198.27.69.191 (8): ########
82.202.69.253 (2): ##
cat ios-example.com.access | sort | uniq -c | awk 'ht="#"{for(i=1;i<$1;i++){ht=ht"#"} str=sprintf("%s (%d): %s", $2,$1, ht); print str}'
expecting file with content like:
ipadress1
ipadress1
ipadress1
ipadress2
ipadress2
ipadress1
ipadress2
ipadress1
Using xargs with sh and printf. Comments in between the lines. Live version at tutorialspoint.
# sorry cat
cat <<EOF |
8 192.27.69.191
2 82.202.69.253
EOF
# for each 2 arguments
xargs -n2 sh -c '
# format the output as "$2 ($1): "
printf "%s (%s): " "$2" "$1"
# repeat the character `#` $1 times
seq "$1" | xargs printf "#%.0s"
# lastly a newline
printf "\n"
' --
I think we could shorten that a bit with:
xargs -n2 sh -c 'printf "%s (%s): %s\n" "$2" "$1" $(printf "#%.0s" $(seq $1))' --
or maybe just echo, if the input is sufficiently safe:
xargs -n2 sh -c 'echo "$2 ($1): $(printf "#%.0s" $(seq $1))"' --
You can upgrade your command by adding another awk to the list, or you can just use a single awk for the whole thing:
awk '{a[$1]++}
END { for(i in a) {
printf "%s (%d):" ,i,a[i]
for(j=0;j<a[i];++j) printf "#"; printf "\n"
}
}' file

Arguments to change variable values in Bash script

i have this script in bash:
#!/bin/bash
dir="/home/dortiz/Prueba"
for i in $dir/*
do
cat $i | awk '{print $1" " $2" " $3" " $4"\n " $5}' | \
awk '/gi/{print ">" $0; getline; print}' | \
awk '$3>20.00 {print $0; getline; print;}' \
> "${i}.outsel"
done
cd /home/dortiz/Prueba
mv *.outsel /home/dortiz/Prueba2
and i would like to set an argument to change the value after ""awk '$3>"" in an easy way from my main program that will call this script.
i have read something about getopts but i dont uderstand it at all
Thanks a lot in advance
The simplest way is to just pass an argument to your script:
yourscript.sh 20.0
Then in your script
#!/bin/bash
value=$1 # store the value passed in as the first parameter.
dir="/home/dortiz/Prueba"
for i in $dir/*; do
awk '{print $1" " $2" " $3" " $4"\n " $5}' "$i" |
awk '/gi/{print ">" $0; getline; print}' |
awk -v val="$value" '$3>val {print $0; getline; print;}' > "${i}.outsel"
# ^^^^^^^^^^^^^^^
done
...
and the cat|awk|awk|awk pipeline can probably be written like this:
awk -v val="$value" '
$3 > val {
prefix = /gi/ ? ">" : ""
print prefix $1 " " $2" " $3" " $4"\n " $5
}
' "$i" > "$i.outsel"

How to reorder a sequence of 4 numbers in a string using bash script on unix

I have the following script:
#!/bin/bash
EXTENT=`ogrinfo -so area.geojson ogrgeojson | grep Extent | sed 's/Extent: //g' | sed 's/(//g' | sed 's/)//g' | sed 's/ - /, /g'`
echo $EXTENT
EXTENT=`echo $EXTENT | awk -F ',' '{print $1 " " $4 " " $3 " " $2}'`
echo $EXTENT
and for some reason it eats up some of the numbers and output:
12.834778, 52.014472, 13.610687, 52.399905
13.610687 52.014472
where expected on the second line is the 4 numbers.
The thing that I do not understand is that, if i copy paste the 4 commands myself to terminal everything works as expected. What do i need to do to make it work in a bash script?
The only way I found to reproduce your problem was this:
$ echo $'12.834778\r, 52.014472\r, 13.610687\r, 52.399905' |
awk -F ',' '{print $1 " " $4 " " $3 " " $2}'
52.014472 13.610687
Please remove the "carriage returns" in your file and you should be fine.

bash command substitution force to foreground

I have this:
echo -e "\n\n"
find /home/*/var/*/logs/ \
-name transfer.log \
-exec awk -v SUM=0 '$0 {SUM+=1} END {print "{} " SUM}' {} \; \
> >( sed '/\b0\b/d' \
| awk ' BEGIN {printf "\t\t\tTRANSFER LOG\t\t\t\t\t#OF HITS\n"}
{printf "%-72s %-s\n", $1, $2}
' \
| (read -r; printf "%s\n" "$REPLY"; sort -nr -k2)
)
echo -e "\n\n"
When run on a machine with bash 4.1.2 always returns correctly except I get all 4 of my new lines at the top.
When run on a machine with bash 3.00.15 it gives all 4 of my new lines at the top, returns the prompt in the middle of the output, and never completes just hangs.
I would really like to fix this for both versions as we have a lot of machines running both.
Why make life so difficult and unintelligible? Why not simplify?
TXFRLOG=$(find /home..... transfer.log)
awk .... ${TXFRLOG}
The answer I found was to use a while read
echo -e "\n\n"; \
printf "\t\t\tTRANSFER LOG\t\t\t\t\t#OF HITS\n"; \
while read -r line; \
do echo "$line" |sed '/\b0\b/d' | awk '{printf "%-72s %-s\n", $1, $2}'; \
done < <(find /home/*/var/*/logs/ -name transfer.log -exec awk -v SUM=0 '$0 {SUM+=1} END{print "{} " SUM}' {} \;;) \
|sort -nr -k2; \
echo -e "\n\n"

how can you change a column of numbers to a space separated list in bash

How can i take the output of this command...
ps -ef | grep ^apache | grep /sbin/httpd | awk '{print $2}'
16779
16783
16784
16785
16786
16787
16788
16789
16790
16794
16795
16796
16797
16799
16800
16801
16802
16803
16804
16805
...so a single column of numbers... and transform those numbers into a single line of numbers separated by a " -p "... This would be used for the following...
lsof -p 16779 -p 16783 -p 16784 ...
Pipe into
sed 's/^/-p /' | tr '\n' ' '
If you have it available, pidof would be more convenient:
lsof $(pidof apache | sed 's/^\| / -p /g')
You could pipe into awk:
awk 'BEGIN { printf "lsof" } { printf " -p %s", $1 } END { printf "\n" }'
Result:
lsof -p 16779 -p 16783 -p 16784 -p 16785 -p 16786 -p 16787 -p 16788 -p 16789 -p 16790 -p 16794 -p 16795 -p 16796 -p 16797 -p 16799 -p 16800 -p 16801 -p 16802 -p 16803 -p 16804 -p 16805
tmp="lsof "
for i in `ps -ef | awk '/^apache/ && /httpd/ {print $2}'`;
do
tmp=${tmp}" -p "${i}" ";
done
echo $tmp
Should do the trick
In a command substitution, the newlines from the pipeline will be converted to spaces.
pids=$( ps -ef | awk '/^apache/ && /\/sbin\/httpd/ {print $2}' ) )
Then a call to printf can be used to format the options for lsof. The format string is repeated as necessary for each argument contained in pids.
lsof $( printf "-p %s " $pids )
Add the following code to your one liner:
awk '{print $0 " -p "}' | tr '\n' ' ' | awk -F " " '{print "lsof -p " $0}'
Final code :
ps -ef | grep ^apache | grep /sbin/httpd | awk '{print $2}' | awk '{print $0 " -p "}' | tr '\n' ' ' | awk -F " " '{print "lsof -p " $0}'

Resources