problem in using awk - shell

i couldn't solve this. when i execute this program i get the following error
" line 7: unexpected EOF while looking for matching `'' "
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '\
{
var2=`echo $var1 | awk -F"a"
{print " "$2}'`
}\
fi
Update: from other, recently closed question
To be more specific, this is my project code
if [ "$FORMAT" = "java" ]; then
cat $INPUT_FILE | awk -F":" '\
/^$/ { print "" }\
/^\/\/.*/ { print " "$0}\
/:string:/ { print " public static final String "$1" = "$3";" }\
/:char:/ { print " public static final char "$1" = "$3";" }\
/:ullong:/ { print " public static final long "$1" = "$3";" }\
/:ulong:/ { print " public static final int "$1" = "$3";" }\
/:long:/ { print " public static final int "$1" = "$3";" }\
' >> $CONST_FILE
fi;
Now i need to truncate $3 (this value is actually read from another file) into two parts(only for ullong). lets say
$3=1256985361455ULL
i need to truncate into 1256985361455 and ULL. (only when it is ullong)
please help me out in this issue.
i tried using another awk inside the the following, but ended up in chaos.
/:ullong:/ { print " public static final long "$1" = "$3";" }\

If you expect the value of $3 for the ullong records to be something like "1256985361455ULL" then
/:ullong:/ {
sub(/ULL$/, "", $3)
print " public static final long "$1" = "$3";"
}

Your quoting problem is because once you start a back-quoted command, it continues until the next back-quote. This is your code as shown above, except I've removed the blank lines.
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '\
{
var2=`echo $var1 | awk -F"a"
{print " "$2}'`
}\
fi
(Back-quotes '`' are hard to show in in-line Markdown.)
The line var1= line starts a back-quoted expression, which stops at the next unescaped back-quote, which is the one after var2=. It then reads the rest of that line, and on the following line, encounters a single quote. When it looks for the following single quote, there is none - so it reports an error. You can demonstrate this is what goes on in steps:
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '\
{
var2=\`echo $var1 | awk -F"a"
{print " "$2}'`
}\
fi
The script above has an escape (backslash) before the back-quote after var2=, so now the command in back-quotes extends to the back-quote after the print line. This still isn't valid shell; the line with }\ combines with the fi to make a command name }fi, so you still get an unexpected EOF error - because the fi for the end of the if is missing. Modify the script again:
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '\
{
var2=\`echo $var1 | awk -F"a"
{print " "$2}'`
#}\
fi
This comments out the close brace, and the shell script is now 'valid'; it is awk's turn to start complaining about the invalid script it is given.
++ awk -FU '{
var2=`echo $var1 | awk -F"a"
{print " "$2}'
awk: syntax error at source line 2
context is
>>> var2=` <<<
awk: illegal statement at source line 2
awk: illegal statement at source line 2
missing }
Other people have given you roughly what you need as an answer. I'd probably use Perl to do the splitting up (and I suspect I could lose the intermediate array #x if I spent enough time on it, producing a script of line noise):
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]
then var1=$(echo $a | perl -ne '#x=split /[aU]/; print "$x[1]\n"')
fi
However, you can also do it in one line with awk, thus:
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]
then var1=$(echo $a | awk -Fa '{sub("ULL","",$2); print $2}')
fi
This splits the input on the 'a' instead of the 'U'; it then removes the 'ULL' from the second field and prints it. If you want to split on 'U', then you use:
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]
then var1=$(echo $a | awk -FU '{sub("[0-9]+a", "", $1); print $1}')
fi
The regular expression in the sub is marginally more complex this way.

Not sure exactly what you are trying to do, but this slight re-write printed out the middle part of a (which is I think what you wanted)
> cat moo.sh
a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F"U" '{print $1}'`
var2=`echo $var1 | awk -F"a" '{print " "$2}'`
echo $var2
fi
> sh moo.sh
1504606846976

You can't do shell commands inside awk except to make system calls. without you telling us what you are trying to achieve
#!/bin/bash
a=115292a1504606846976ULL
b=2
case "$b" in
2 )
a=${a%U*}
echo ${a#*a} # I assume you want to get 1504606846976
esac

a=115292a1504606846976ULL
b=2
if [ "$b" = "2" ]; then
var1=`echo $a | awk -F "U" '{print $1}' | awk -F "a" '{print $2}'`
fi

Related

Testing grep output

The cmd:
STATUS=`grep word a.log | tail -1 | awk '{print $1,$2,$7,$8,$9}'`
echo "$STATUS"
The output:
2020-05-18 09:27:01 1 of 122
I need to display this $STATUS and need to do the test comparison as well.
How to compare number 122 in below? How to represent 122 in $X?
The number 122 can be any number, resulted from above cmd.
if [ "$X" -gt "300" ]
then
echo "$STATUS. This in HIGH queue ($X)"
else
echo "$STATUS. This is NORMAL ($X)"
fi
You could do it with one awk script:
awk '
/word/{ status=$1" "$2" "$7" "$8" "$9; x=$9 }
END{ printf status". This %s (%s)\n", (x>300 ? "in HIGH queue" : "is NORMAL"), x }
' a.log
I would suggest using lowercase for variables to reduce possible confusion for someone other than the original author reading the script in the future. Also using $() is typically preferable to using back-ticks -- makes quoting easier to get right.
status="$(grep word a.log | tail -1 | awk '{print $1,$2,$7,$8,$9}')"
x="$(printf '%s' "$status" | awk '{ print $NF }')"
if [ "$x" -gt 300 ]
then
echo "$status. This in HIGH queue ($x)"
else
echo "$status. This is NORMAL ($x)"
fi
Note -- we could refactor the status line a bit:
status="$(awk '/word/ { x = $1 OFS $2 OFS $7 OFS $8 OFS $9 } END { print x }' a.log)"

Using shell for loop deal with json

Here is my shell code,My question is I don't want the ',',at the end of json file.
#!/bin/bash
PATCH_VERSION_FILE=/root/workspace/patch_version.json
filepath=/root/workspace/txtdir
for file in "${filepath}"/*.txt; do
echo " {" >> ${PATCH_VERSION_FILE}
filename=`echo ${file} | awk -F'/' '{ print $(NF) }'`
filemd5=`md5sum "${file}" | awk '{ print $1 }'`
echo " \"${filename}\"":"\"$filemd5\"">>${PATCH_VERSION_FILE}
echo " },">>${PATCH_VERSION_FILE}
done
Output:
{
"2001.txt":"d41d8cd98f00b204e9800998ecf8427e"
},
{
"2002.txt":"d41d8cd98f00b204e9800998ecf8427e"
},
{
"2003.txt":"d41d8cd98f00b204e9800998ecf8427e"
},
{
"2004.txt":"d41d8cd98f00b204e9800998ecf8427e"
},
{
"2005.txt":"d41d8cd98f00b204e9800998ecf8427e"
},
I found a soulution,but it looks ugly,the code below:
n=0
for file in "${filepath}"/*.txt; do
if [ $n -ne 0 ];then
echo " ," >> ${PATCH_VERSION_FILE}
fi
echo " {" >> ${PATCH_VERSION_FILE}
filename=`echo ${file} | awk -F'/' '{ print $(NF) }'`
filemd5=`md5sum "${file}" | awk '{ print $1 }'`
echo " \"${filename}\"":"\"$filemd5\"">>${PATCH_VERSION_FILE}
echo " }">>${PATCH_VERSION_FILE}
n=$(( $n + 1 ))
done
but the ',' not the same line with '}',is there any ways to deal with this ?
You could add this at the end of your script (after your for loop). It will simply remove (actually will replace with empty string) the last character of the file :
sed -i '$ s/.$//' $PATCH_VERSION_FILE
In order to have valid JSON data, you can use a JSON aware tool like jq:
md5sum "$filepath"/*.txt | jq -R 'split(" ")|{(.[1]):.[0]}' >> ${PATCH_VERSION_FILE}
-R option allows jq to read strings from md5sum.
The string is splitted in 2 and then assigned to the key/value object.

string comparison with output in Bash

I have a simple script that works great (and prints hello)
variable=false
if [ "$variable" = "false" ]; then
echo hello
fi
However, this does not work (and does not print hello)
variable=$(source script.sh \
| awk -F":" '/maintenanceMode\>/ { print $2i }' \
| sed 's/,//g'
)
echo $variable # prints `false`, as expected
if [ "$variable" = "false" ]; then
echo hello
fi
What am I missing?
Strip whitespaces from your variable.
$variable=`echo $variable | xargs`

Awk shell scripting using gsub to remove whitespace

I have a shell script that I would like to export out the 'data' variable without any whitespace in it. I have tried gsub() but I cannot seem to get it work.
export data="`grep -e 'P/N :' "$xfile" | awk '{print substr($3,3)}' `"
if [ "$data" = "" ] && [ "$skipdata" = "0" ]
then
export data="`grep -e 'P/N:' "$xfile" | awk '{print substr($2,3)}' |
awk '{ if (index($1,"-D") != 0)
$1 = (substr($1, 1, (index($1,"-D") -1))) "-DIE" }
{ print $1 }' `"
if [ "$data" = "" ]
then
export data="`grep -e 'CUST PART NO:' "$xfile" | awk '{print substr($4,3)}' |
awk '{ if (index($1,"-D") != 0)
$1 = (substr($1, 1, (index($1,"-D") -1))) "-DIE" }
{ print $1 }' `"
fi
fi
Ultimately I would like $data to be whitespace free. Can I do like:
export data="awk '{gsub($data," ","");print}"
It LOOKS like your script should be written as just something like:
data=$(awk -F':' '
$1 ~ /^(P\/N[[:space:]]*|CUST PART NO)$/ {
sub(/-D.*/,"-DIE",$2)
gsub(/[[:space:]]+/,"",$2)
print $2
}
' "$xfile")
We can use that as a starting point and if it doesn't do exactly what you want then update your question to include some sample lines from $xfile and your desired output.
I think the correct syntax is
gsub(/[[:blank:]]+/,"")
so you could probably use
data=$(awk '{gsub(/[[:blank:]]+/,""); print}' <<< "$data")

bash script: commands after the loop are not executed if the loop condition is false

I have a strange behavior in my script bash. when the while condition is true the script behaves correctly but if it's false the commands after the loop aren't executed at all and the script stops. There is no break in my commands after the loop.
I cannot see where is the problem! Any help is welcome :)
Thanks in advance.
while [ expression1 ] || [ expression2 ]
do
echo in the loop
if [ expression3 ] && [ expression4 ] ;
then
commands..
break;
fi
commands..
done
commands..
echo out from the loop
Real code:
start_t=`grep Start_t $job_template | awk -F= '{print $2}'`
current_date=`date +%s`
progress_t=`expr $current_date - $start_t`
exec_t=`grep Exec_t $job_template | awk -F= '{print $2}'`
running_state="r"
req_state $job_id # get the state
xml_state=` grep "job_id=$job_id" $list_job_file | awk '{print $4}'`
while [ $state = $running_state ] || [ $xml_state = "stoped" ]
do
echo in the loop
if [ "$xml_state" = "running" ] && [ $progress_t -gt $exec_t ] ;
then
kill_job $job_id
update_status $job_template "killed"
echo The job is killed
break;
fi
sleep $sleeping_t
$req_state $job_id # to update the state
echo state $state
xml_state=` grep "job_id=$job_id" $list_job_file | awk '{print $4}' `
echo xml_state $xml_state
start_t=`grep Start_t $job_template | awk -F= '{print $2}'`
current_date=`date +%s`
progress_t=`expr $current_date - $start_t`
done
echo out from the loop
commands..
There are many mistakes in this script :
state is not initialised
as test are done with single right bracket, the variables should be double quoted to avoid shell expansion
seems req_state is a function or a command, so there must not be preceded by a $
useless use of grep with awk : grep Start_t $job_template | awk -F= '{print $2}' and awk -F= '/Start_t/{print $2}' $job_template will do the same thing.

Resources