Using output of awk to run command
Use system
from within awk:
awk '{ system("openssl s_client -connect host:port -cipher " $1) }' ciphers.txt
Execute awk output
| bash
does the trick...
while read line;
do
awk '/ differ$/ {print "diff "$2" "$4" > "$2".diff"}{}' | bash;
done < diffs.txt
Assigning system command's output to variable
Figured out.
We use awk's Two-way I/O
{
"strip $1" |& getline $1
}
passes $1 to strip and the getline takes output from strip back to $1
Execute bash command inside awk and print command output
Just do the string reversal and translation in awk itself:
$ awk '
BEGIN {
old="ATGC"
new="TACG"
for (i=1;i<=length(old);i++) {
tr[substr(old,i,1)] = substr(new,i,1)
}
}
{
newVar=""
for (i=1;i<=length($3);i++) {
char = substr($3,i,1)
newVar = (char in tr ? tr[char] : char) newVar
}
print $1, $2, newVar, $4
}
' file
ABC DEF CTAATC GHK
ABC DEF GACGCC GHK
ABC DEF GGAATT GHK
If you really feel a burning need to call an external tool from awk and read the result back that'd be:
$ awk '
{
cmd="echo \047" $3 "\047 | rev | tr \047ATGC\047 \047TACG\047"
newVar=((cmd | getline line) > 0 ? line : "failed")
close(cmd)
print $1, $2, newVar, $4
}
' file
ABC DEF CTAATC GHK
ABC DEF GACGCC GHK
ABC DEF GGAATT GHK
but you should expect a significant performance hit from doing that and see also the getline caveats: http://awk.freeshell.org/AllAboutGetline.
Run Shell Command Inside Awk only Once 'per command' Using System(), i e, print only Once text
Primary issue (repeated text/text2
entries on stdout) comes from what appears to be a dual use of the awk
variable k
and some missing input control.
The awk
variable k
is being used as an auto-incremented index by the 2nd and 3rd gsub(... k++ ...)
calls; at no point is k
reset to 0
(or 1
) so logically speaking OPs k==1
tests should only occur once. However ...
The tests for k==1
will occur for every input line (from all files) ... this occurs for lines with and without the home_cool
string; and because there are two k==1
tests being validated for each input line OP is going to get double outputs (text
and text2
) as long as k==1
.
Also keep in mind that k
is only being incremented (by the gsub()
calls) for lines with the string home_cool
; net result is lines without home_cool
will see k==1
unchanged so the two k==1
tests will fire for these lines, too; we'll get extra text/text2
entries on stdout until the next gsub()
fires and increments k
(via the k++
)
I'd suggest using a different variable (eg, p
) to determine when to print the text/text2
entries, and moving the k==1
tests (now if (p)
) to a location where they are only run when appropriate.
One idea for a rewrite:
awk '
FNR==1 {++f; p=1} # reset our "p"rintme? flag for each new file
f==1 {a[i++]=$0}
f==2 {if ($0~/home_cool/)
{gsub(/home_cool/, a[int(j++/2)%2]) }
print > "2.txt"
}
f==3 {if ($0~/home_cool/)
{gsub(/home_cool/, a[int(k++/2)%3 + 2])}
if (p) # old "k==1" test; if "p"rintme flag set then ...
{print "text"; system("sleep 4"); p=0} # print, sleep, clear flag
print > "3.txt"
}
f==4 {if ($0~/home_cool/)
{gsub(/home_cool/, a[int(k++/2)%3 + 2])}
if (p) # old "k==1" test; if "p"rintme flag set then ...
{print "text2"; system("sleep 4"); p=0} # print, sleep, clear flag
print > "4.txt"
}
' 1.txt 0.txt 0-1.txt 0-2.txt
When run this generates the following on stdout:
text
text2
NOTES:
- other than the print issues I'm assuming OP's logic is correct (ie, the contents of the
[234].txt
files are correct) - if an input file is empty then the associated
f==?
test will not fire which means ... - the associated
if (p)...
test/operation will not fire; - for example ...
- if
0-2.txt
is empty thenf==4
will never test as positive so ... - the associated
if (p) ... print "text2" ...
will not fire - it's not clear (to me) if OP needs to conditionally print the
text/text2
messages if the corresponding files are empty ... - easy enough to modify the code but I'll skip that for now so as to limit the confusion
How can I pass variables from awk to a shell command?
you are close. you have to concatenate the command line with awk variables:
awk '{system("wc "$1)}' myfile
awk: how to execute a command and read its output
Just in case there's yet another getline caveat kicking in here (see http://awk.info/?tip/getline), try closing the pipe after every invocation, e.g.:
ping eulbi001 |
awk -F'[ =]' 'BEGIN{cmd="date +%s"} /64 bytes/{cmd|getline D; close(cmd); print D,$11}'
and see if you get different results. You still shouldn't expect D to change on every invocation though, just every second. You could add a ".%N" for smaller granularity of your timestamps if you like.
Better yet, use GNU awk with it's builtin time functions so you don't need to deal with this stuff at all.
Related Topics
Differencebetween "Var=${Var:-Word}" and "Var=${Var:=Word}"
Run a Persistent Process via Ssh
How to Run the Cron Job as a User Instead of Root User
How to Toggle Cr/Lf in Gnu Screen
Merging Through Fuzzy Matching of Variables in R
How to Send Multicast Packets via a Specfic Interface in Linux
What Does -Prune Option in Find Do
Get Time in Milliseconds Without an Installing an Extra Package
Git Unable to Create File Permission Denied
Clean Server Infected with C3284D Virus, Using Search and Replace
Unix 'Alias' Fails with 'Awk' Command
How to Install a Rpm Package and Its Dependencies Offline
Add Blank Line After Every Result in Grep
How to Create a JSON Web Token (Jwt) Using Openssl Shell Commands
Compiling Out-Of-Tree Kernel Module Against Any Kernel Source Tree on the Filesystem
How to Translate Linux Keycodes from /Dev/Input/Event* to Ascii in Perl
How Do Locales Work in Linux/Posix and What Transformations Are Applied