I'm tweaking a KSH script and I'm trying to ssh into various hosts and execute a grep command on vfstab that will return a certain line. The problem is, I can't get the following to work below. I'm trying to get the line it returns and append it to a destination file. Is there a better way to do this, ex assign the grep statement to a command variable? The command works fine within the script, but the nested quotations seems to bugger it. Anyways, here's the line:
ssh $user#$host "grep '/var/corefiles' $VFSTAB_LOC | awk '{print $3, $7}' " >> $DEST
This results in:
awk: syntax error near line 1
awk: illegal statement near line one
If there is a better/more correct way to do this please let me know!
You're putting the remote command in double quotes, so the $3 and $7 in the awk body will be substituted. awk probably sees '{print ,}'. Escape the dollar signs in the awk body.
ssh $user#$host "grep '/var/corefiles' $VFSTAB_LOC | awk '{print \$3, \$7}' " >> $DEST
^ ^
I tried below and it worked for me (in ksh) not sure why it would error out in your case
user="username";
host="somehost";
VFSTAB_LOC="result.out";
DEST="/home/username/aaa.out";
echo $DEST;
`ssh $user#$host "grep '/abc/dyf' $VFSTAB_LOC | awk '{print $3, $1}'" >> $DEST`;
Related
#!/usr/bin/expect -f
set name [lindex $argv 0]
send "grep $name /usr/local/bin/c | awk '{print $3}' | awk '{print substr($1,10)}'\r"
spawn grep $name /usr/local/bin/c | awk '{print $3}' | awk '{print substr($1,10)}'
I have tried "\" escaping quotes and special symbols. It doesn't work. I also have tried to send and spawn. Doesn't work. If I run just the grep........... command on the line it returns what I need. Any help on how to get this to run from my expect file would be great. Thanks.
Single quotes have no special meaning in expect. Use braces instead for the same effect:
spawn awk -v n="perferx" {$0 ~ n {print substr($3,10,5)}} /usr/local/bin/c
# .......................^..............................^
Ref: Tcl syntax rules, #6
No substitutions are performed on the characters between the braces
Additionally, without seeing what you're doing with the output, perhaps you don't need spawn
set output [exec awk -v n="perferx" {$0 ~ n {print substr($3,10,5)}} /usr/local/bin/c]
Now, you can do simple string parsing on $output
If relevant I have GNU awk V 3.1.6 downloaded directly from GNU pointed source in sourceforge.
I am getting a page of URLs using wget for windows. After prcoessing the incoming file, I reduce it to single line, from which I have to extract a key value, which is quite a long string. The final line looks something like this:
<ENUM_TAG>content"href:e#5nUtw3Fc^b=tZjqpszvja$sb=Lp4YGH=+J_XuupctY9zE9=&KNWbphdFnM3=x4*A#a=W4YXZKV3TMSseQx66AHz9MBwdxY#B#&57t3%s6ZyQz3!aktRNzcWeUm*8^$B6L&rs5X%H3C3UT&BhnhXgAXnKZ7f2Luy*jYjRLLwn$P29WzuVzKVnd3nVc2AKRFRPb79gQ$w$Nea6cA!A5dGRQ6q+L7QxzCM%XcVaap-ezduw?W#YSz!^7SwwkKc"</ENUM_TAG>
I need the long string between the two " signs.
So I use this construct with awk
type processedFile | awk -F "\"" "{print $2}"
and I get the output as expected
href:e#5nUtw3Fc^b=tZjqpszvja$sb=Lp4YGH=+J_XuupctY9zE9=&KNWbphdFnM3=x4*A#a=W4YXZKV3TMSseQx66AHz9MBwdxY#B#&57t3%s6ZyQz3!aktRNzcWeUm*8^$B6L&rs5X%H3C3UT&BhnhXgAXnKZ7f2Luy*jYjRLLwn$P29WzuVzKVnd3nVc2AKRFRPb79gQ$w$Nea6cA!A5dGRQ6q+L7QxzCM%XcVaap-ezduw?W#YSz!^7SwwkKc
but when I run the same command with output redirected to a file, such as
type processedFile | awk -F "\"" "{print $2}" > tempDummy
I get this error message:
awk: cmd. line:1: fatal: cannot open file `>' for reading (Invalid argument)
I am thinking the \" field separator is causing me some grief and making the last " character as a non-closed string value, but I am not sure how to make this right. The same construct runs on my centos box perfectly well by the way.
Any pointers are greatly appreciated. I tried reading all the readme files I could find but none of them touches the output redirection.
Yes, you have problems with how cmd parser deals with where quoted areas start/end. What cmd sees is
awk -F "\"" "{print $2}" > tempDummy
^-^^-^ ^-------------
1 2 3
that is, three quoted areas. As the > falls inside a quoted area it is not handled as a
redirection operator, it is an argument to the command in the rigth side of the pipe.
This can be solved by just escaping (^ is cmd's general escape character) a quote to ensure cmd properly generates the final command after parsing the line and that the redirection is not part of the awk command
type processedFile | awk -F ^"\"" "{print $2}" > tempDummy
^^ ^..........^
Or you can reorder the command to place the redirection operation where it could not interfere
type processedFile | > tempDummy awk -F "\"" "{print $2}"
but while this works using this approach may later fail in other cases because the awk code ({print $2}) is placed in an unquoted area.
There is a simpler, standard, portable way of doing it without having to deal with quote escaping: instead of passing the quote as argument it is better to use the awk string handling and just include the escape sequence of the quote character
type processedFile | awk -F "\x22" "{print $2}" > tempDummy
You were close. The issue here is that you are mixing awk redirection with cmd one.
For completness sake I'm using MSYS2 awk version (version should not matter in this issue):
awk --version
GNU Awk 4.2.1, API: 2.0 (GNU MPFR 4.0.1, GNU MP 6.1.2)
Windows version is in this case irrelevant - will work both on Win7 and Win10
Your command:
type processedFile | awk -F "\"" "{print $2}" > tempDummy
uses > which you expect to be a cmd.exe redirection, but awk expects a file, thus you get the error: awk: cmd. line:1: fatal: cannot open file ``>'
1) Fixing the redirection
You can fix that by doing the redirection directly at awk:
type processedFile | awk -F "\"" "{ print $2 > "tempDummy"; }"
2) Using awk to read the file
The type command is here superfluous as you can use directly awk to read the file:
awk -F "\"" "{ print $2 > "tempDummy"; }" processedFile
Don't forget note: What is important to note is that GNU utils are case sensitive but the default filesystem settings at windows is case-insensitive.
I am not much of an awk user, but after some Googling, determined it would work best for what I am trying to do...only problem is, I can't get it to work. I'm trying to print out the contents of sudoers while inserting the server name ($i) and a comma before the sudoers entry as I'm directing it to a .csv file.
egrep '^[aA-zZ]|^[%]' //$i/etc/sudoers | awk -v var="$i" '{print "$var," $0}' | tee -a $LOG
This is the output that I get:
$var,unixpvfn ALL = (root)NOPASSWD:/usr/bin/passwd
awk: no program given
Thanks in advance
egrep is superfluous here. Just awk:
awk -v var="$i" '/^[[:alpha:]%]/{print var","$0}' //"$i"/etc/sudoers | tee -a "$LOG"
Btw, you may also use sed:
sed "/^[[:alpha:]%]/s/^/${i},/" //"$i"/etc/sudoers | tee -a "$LOG"
You can save the grep and let awk do all the work:
awk -v svr="$i" '/^[aA-zZ%]/{print svr "," $0}' //$i/etc/sudoers
| tee -a $LOG
If you put things between "..", it means literal string, and variable won't be expanded in awk. Also, don't put $ before a variable, it will indicate the column, not the variable you meant.
Attempting to get the last word of the first line from a file. Not sure why the following command:
send "cat moo.txt | grep QUACK * | awk 'NF>1{print $NF}' meow.txt >> bark.txt "
is getting the error message can't read "NF": no such variable.
I can run the awk 'NF>1{print $NF}' meow.txt >> bark.txt snippet just fine on my machine. Yet, when it runs in my expect script, it gives me that error.
Anyone know why expect doesn't recognize the awk built-in variable?
I think your script is trying to expand the variable $NF with it's value before shooting that command through send. $NF isn't set in your shell since it's internal to awk, which hasn't had a chance to even run yet and so it's balking.
Try escaping that variable so it is treated as a string literal and awk will be able to use it when it comes time for awk to run:
send "cat moo.txt | grep QUACK * | awk 'NF>1{print \$NF}' meow.txt >> bark.txt "
I'm writing a shell script and I need to strip FIND ME out of something like this:
* *[**FIND ME**](find me)*
and assign it to an array. I had the code working flawlessly .. until I moved the script in Solaris to a non-global zone. Here is the code I used before:
objectArray[$i]=`echo $line | nawk -F '*[**|**]' '{print $2}'`
Now Prints:
awk: syntax error near line 1
awk: bailing out near line 1
It was suggested that I try the same command with nawk, but I receive this error now instead:
nawk: illegal primary in regular expression `* *[**|**]` at `*[**|**]`
input record number 1
source line number 1
Also, /usr/xpg4/bin/awk does not exist.
I think you need to be clearer on what you want to get. For me your awk line doesn't 'strip FIND ME out'
echo "* *[**FIND ME**](find me)*" | nawk -F '* *[**|**]' '{print $2}'
[
So it would help if you gave some examples of the input/output you are expecting. Maybe there's a way to do what you want with sed?
EDIT:
From comments you actually want to select "FIND ME" from line, not strip it out.
I guess the dialect of regular expressions accepted by this nawk is different than gawk. So maybe a tool that's better suited to the job is in order.
echo "* *[**FIND ME**](find me)*" | sed -e"s/.*\* \*\[\*\*\(.[^*]*\)\*\*\].*/\1/"
FIND ME
quote your $line variable like this: "$line". If still doesn't work, you can do it another way with nawk, since you only want to find one instance of FIND ME,
$ echo "$line" | nawk '{gsub(/.*\*\[\*\*|\*\*\].*/,"");print}'
FIND ME
or if you are using bash/ksh on Solaris,
$ line="${line#*\[\*\*}"
$ echo "${line%%\*\*\]*}"
FIND ME