1. It will generate empty out files.
2. It uses 3 awk calls.
On Wed, 2 Aug 2023 06:19:59 -0700 (PDT), "hongy...@gmail.com" <hongy...@gmail.com> wrote:
1. It will generate empty out files.1) Read the awk manual about redirection
2. It uses 3 awk calls.
2) Rewrite the bash script with one awk invocation
3) Pass the suffix as a variable to awk with
-v suffix=$suffix
4)
BEGIN{} and the body are the same as your current awk scripts
5) In one END{}, use the existing loop three times, with
redirections to each of the files. One example:
END{
...
...
for (j=0;j<i/2;j++){
print a[j],b[j],b[j+i/2]} >"optics-current-" suffix ".dat"
}
}
--
HTH
Kees Nuyt
On Wednesday, August 2, 2023 at 11:58:51 PM UTC+8, Kees Nuyt wrote:
On Wed, 2 Aug 2023 06:19:59 -0700 (PDT), "hongy...@gmail.com"
<hongy...@gmail.com> wrote:
1. It will generate empty out files.1) Read the awk manual about redirection
2. It uses 3 awk calls.
2) Rewrite the bash script with one awk invocation
3) Pass the suffix as a variable to awk with
-v suffix=$suffix
4)
BEGIN{} and the body are the same as your current awk scripts
5) In one END{}, use the existing loop three times, with
redirections to each of the files. One example:
END{
...
...
for (j=0;j<i/2;j++){
print a[j],b[j],b[j+i/2]} >"optics-current-" suffix ".dat"
But how can I know this is corresponding to the case of matched xml tag `<dielectricfunction comment="current-current">'?
More specifically, I want to use the corresponding filename part based on the xml tag programmatically here.
}
}
--
HTH
Kees Nuyt
On 03.08.2023 01:59, hongy...@gmail.com wrote:
On Wednesday, August 2, 2023 at 11:58:51 PM UTC+8, Kees Nuyt wrote:
On Wed, 2 Aug 2023 06:19:59 -0700 (PDT), "hongy...@gmail.com"
<hongy...@gmail.com> wrote:
1. It will generate empty out files.1) Read the awk manual about redirection
2. It uses 3 awk calls.
2) Rewrite the bash script with one awk invocation
3) Pass the suffix as a variable to awk with
-v suffix=$suffix
4)
BEGIN{} and the body are the same as your current awk scripts
5) In one END{}, use the existing loop three times, with
redirections to each of the files. One example:
END{
...
...
for (j=0;j<i/2;j++){
print a[j],b[j],b[j+i/2]} >"optics-current-" suffix ".dat"
But how can I know this is corresponding to the case of matched xml tag `<dielectricfunction comment="current-current">'?You can, for example, simply store the three data types in different
array sets; a1[], b1[], ..., a2[], b2[], ..., a3[], b3[], ...
(and then don't forget to use own index variables i1, i2, i3).
(Also note that the /<dielectricfunction>/ data contains also the other
two data sets; in case that it's not intentional.)
More specifically, I want to use the corresponding filename part based on the xml tag programmatically here.This has already been answered by Kees; pass the suffix to awk...
awk -v suffix="$1" '
...
print a[j],b[j],b[j+i/2]} >"optics-current-" suffix ".dat"
...
'
Janis
}
}
--
HTH
Kees Nuyt
Do you mean something as follows?
#!/bin/bash
[...]
On 03.08.2023 15:43, hongy...@gmail.com wrote:
Do you mean something as follows?
#!/bin/bash
[...]
At a quick first glance I'd say yes, something like that. Does it do
the job as you expect it? - If it does then I'd also consider to use
a function for the whole if-statement and pass the array as argument
(and of course you'd also need to handle the indexes differently).
Maybe something like...
function assign (a, b, c, d, i)
{
i++
if ($1 == "<r>") {
a[i] = $2
b[i] = ($3 + $4 + $5) / 3
c[i] = $4
d[i] = $5
}
return i
}
/<dielectricfunction>/, /<\/dielectricfunction>/ {
i = assign(a, b, c, d, i)
}
/<dielectricfunction comment="density-density">/, /<\/dielectricfunction>/ {
i1 = assign(a1, b1, c1, d1, i1)
}
...etc...
Note: Arrays are passed by reference but scalars not, so you must pass
the index value and return it.
Janis
On 03.08.2023 17:44, Janis Papanagnou wrote:
On 03.08.2023 15:43, hongy...@gmail.com wrote:
Do you mean something as follows?
#!/bin/bash
[...]
At a quick first glance I'd say yes, something like that. Does it do
the job as you expect it? - If it does then I'd also consider to use
a function for the whole if-statement and pass the array as argument
(and of course you'd also need to handle the indexes differently).
Maybe something like...
function assign (a, b, c, d, i)Argh! - I just noticed you start by 0, so remove that i++ here and...
{
i++...add the '++' here...
if ($1 == "<r>") {
a[i] = $2
b[i] = ($3 + $4 + $5) / 3
c[i] = $4
d[i] = $5
}
return i
return ++i
}
/<dielectricfunction>/, /<\/dielectricfunction>/ {
i = assign(a, b, c, d, i)
}
/<dielectricfunction comment="density-density">/, /<\/dielectricfunction>/ {
i1 = assign(a1, b1, c1, d1, i1)
}
...etc...
Note: Arrays are passed by reference but scalars not, so you must pass
the index value and return it.
Janis
On Friday, August 4, 2023 at 12:04:14 AM UTC+8, Janis Papanagnou wrote:
On 03.08.2023 17:44, Janis Papanagnou wrote:
On 03.08.2023 15:43, hongy...@gmail.com wrote:
Do you mean something as follows?
#!/bin/bash
[...]
At a quick first glance I'd say yes, something like that. Does it do
the job as you expect it? - If it does then I'd also consider to use
a function for the whole if-statement and pass the array as argument (and of course you'd also need to handle the indexes differently).
Maybe something like...
function assign (a, b, c, d, i)Argh! - I just noticed you start by 0, so remove that i++ here and...
{
i++...add the '++' here...
if ($1 == "<r>") {
a[i] = $2
b[i] = ($3 + $4 + $5) / 3
c[i] = $4
d[i] = $5
}
return i
return ++i
}
/<dielectricfunction>/, /<\/dielectricfunction>/ {
i = assign(a, b, c, d, i)
}
/<dielectricfunction comment="density-density">/, /<\/dielectricfunction>/ {
i1 = assign(a1, b1, c1, d1, i1)
}
I ran the following tests, but it seems that neither my nor your approach works perfectly:...etc...
$ cat test.xml
<dielectricfunction comment="density-density">
<r> 0.0000 0.0000 0.0000 -0.0000 -0.0000 0.0000 -0.0000 </r>
<r> 0.0200 0.0030 0.0030 0.0030 0.0000 0.0000 0.0000 </r>
<r> 0.0400 0.0059 0.0059 0.0059 0.0000 0.0000 0.0000 </r>
<r> 0.0601 0.0089 0.0089 0.0089 0.0000 0.0000 0.0000 </r>
<r> 0.0801 0.0119 0.0119 0.0119 0.0000 0.0000 0.0000 </r>
<r> 0.1001 0.0149 0.0149 0.0149 0.0000 0.0000 0.0000 </r>
</dielectricfunction>
<dielectricfunction comment="current-current">
<r> 0.0000 0.0000 0.0000 -0.0000 -0.0000 0.0000 -0.0000 </r>
<r> 0.0200 0.0030 0.0030 0.0030 0.0000 0.0000 0.0000 </r>
<r> 0.0400 0.0059 0.0059 0.0059 0.0000 0.0000 0.0000 </r>
<r> 0.0601 0.0089 0.0089 0.0089 0.0000 0.0000 0.0000 </r>
<r> 0.0801 0.0119 0.0119 0.0119 0.0000 0.0000 0.0000 </r>
<r> 0.1001 0.0149 0.0149 0.0149 0.0000 0.0000 0.0000 </r>
</dielectricfunction>
<dielectricfunction>
<r> 0.0000 0.0000 0.0000 -0.0000 -0.0000 0.0000 -0.0000 </r>
<r> 0.0200 0.0030 0.0030 0.0030 0.0000 0.0000 0.0000 </r>
<r> 0.0400 0.0059 0.0059 0.0059 0.0000 0.0000 0.0000 </r>
<r> 0.0601 0.0089 0.0089 0.0089 0.0000 0.0000 0.0000 </r>
<r> 0.0801 0.0119 0.0119 0.0119 0.0000 0.0000 0.0000 </r>
<r> 0.1001 0.0149 0.0149 0.0149 0.0000 0.0000 0.0000 </r>
</dielectricfunction>
$ cat awk.1
#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: $0 <suffix>"
exit 1
fi
suffix=$1
awk -v suffix="$suffix" '
/<dielectricfunction>/, /<\/dielectricfunction>/ {
if ($1 == "<r>") {
a[i] = $2
b[i] = ($3 + $4 + $5) / 3
c[i] = $4
d[i] = $5
i++
}
}
/<dielectricfunction comment="density-density">/, /<\/dielectricfunction>/ { if ($1 == "<r>") {
a1[i1] = $2
b1[i1] = ($3 + $4 + $5) / 3
c1[i1] = $4
d1[i1] = $5
i1++
}
}
/<dielectricfunction comment="current-current">/, /<\/dielectricfunction>/ { if ($1 == "<r>") {
a2[i2] = $2
b2[i2] = ($3 + $4 + $5) / 3
c2[i2] = $4
d2[i2] = $5
i2++
}
}
END {
for (j = 0; j < i / 2; j++) {
print a[j], b[j], b[j + i / 2] > "optics-" suffix ".dat"
}
for (j = 0; j < i1 / 2; j++) {
print a1[j], b1[j], b1[j + i1 / 2] > "optics-density-" suffix ".dat"
}
for (j = 0; j < i2 / 2; j++) {
print a2[j], b2[j], b2[j + i2 / 2] > "optics-current-" suffix ".dat"
}
}
' test.xml
$ cat awk.2
#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: $0 <suffix>"
exit 1
fi
suffix=$1
awk -v suffix="$suffix" '
function assign (a, b, c, d, i)
{
if ($1 == "<r>") {
a[i] = $2
b[i] = ($3 + $4 + $5) / 3
c[i] = $4
d[i] = $5
}
return i
i++
}
/<dielectricfunction>/, /<\/dielectricfunction>/ {
i = assign(a, b, c, d, i)
}
/<dielectricfunction comment="density-density">/, /<\/dielectricfunction>/ { i1 = assign(a1, b1, c1, d1, i1)
}
/<dielectricfunction comment="current-current">/, /<\/dielectricfunction>/ { i1 = assign(a1, b1, c1, d1, i1)
}
END {
for (j = 0; j < i / 2; j++) {
print a[j], b[j], b[j + i / 2] > "optics-" suffix ".dat"
}
for (j = 0; j < i1 / 2; j++) {
print a1[j], b1[j], b1[j + i1 / 2] > "optics-density-" suffix ".dat"
}
for (j = 0; j < i2 / 2; j++) {
print a2[j], b2[j], b2[j + i2 / 2] > "optics-current-" suffix ".dat"
}
}
' test.xml
The tests are as follows:
First test my original script:
$ bash awk.1 dft
$ cat optics-dft.dat
0.0089
0.0200 0.003 0.0119
0.0400 0.0059 0.0149
$ cat optics-current-dft.dat
0.0089
0.0200 0.003 0.0119
0.0400 0.0059 0.0149
$ cat optics-density-dft.dat
0.0089
0.0200 0.003 0.0119
0.0400 0.0059 0.0149
As you can see, the first line in the result only has one column.
Then I will test the version based on your suggested improvements:
$ rm *dat
$ bash awk.2 dft
$ ls *dat
ls: cannot access '*dat': No such file or directory
As you can see, nothing is generated at all.
Note: Arrays are passed by reference but scalars not, so you must pass the index value and return it.
ZhaoJanis
On Friday, August 4, 2023 at 10:53:33 AM UTC+8, hongy...@gmail.com wrote:
I ran the following tests, but it seems that neither my nor your approach works perfectly:
return i
i++
Change to the following does the trick:
[...]
if ($1 == "<r>") {
i++
On 04.08.2023 08:39, hongy...@gmail.com wrote:
On Friday, August 4, 2023 at 10:53:33AM UTC+8, hongy...@gmail.com wrote:
I ran the following tests, but it seems that neither my nor your approach >works perfectly:
I merely tried to show you the direction. I haven't analyzed
the code, just transcribed it a bit.
return i
i++
(The increment will not be reached. I meant to use 'return ++i'.)
I note that your general approach is that you have multiple arrays, running multiple counters (i, i1, etc) - one counter for each array.
In situations like this, I often use the trick of storing the counter in
the zero element of each array. So, you end up with something like:
A[++A[0]] = "something"
Also, OP might consider using a single, multi-dimensional array, instead of multiple arrays (a,b,c,d). I often find this works better. Of course, you have to be running a version of AWK that supports real multi-dimensional arrays (i.e., TAWK or GAWK).
I'd be willing to bet that OP either is or should be running GAWK.
In article <uailea$18aba$1...@dont-email.me>,
Janis Papanagnou <janis_pap...@hotmail.com> wrote:
On 04.08.2023 08:39, hongy...@gmail.com wrote:
On Friday, August 4, 2023 at 10:53:33AM UTC+8, hongy...@gmail.com wrote: >>> I ran the following tests, but it seems that neither my nor your approachworks perfectly:
I merely tried to show you the direction. I haven't analyzed
the code, just transcribed it a bit.
return i
i++
(The increment will not be reached. I meant to use 'return ++i'.)I note that your general approach is that you have multiple arrays, running multiple counters (i, i1, etc) - one counter for each array.
In situations like this, I often use the trick of storing the counter in
the zero element of each array. So, you end up with something like:
A[++A[0]] = "something"
Also, OP might consider using a single, multi-dimensional array, instead of multiple arrays (a,b,c,d). I often find this works better. Of course, you have to be running a version of AWK that supports real multi-dimensional arrays (i.e., TAWK or GAWK).
I'd be willing to bet that OP either is or should be running GAWK.
--
I love the poorly educated.
I note that your general approach is that you have multiple arrays, running multiple counters (i, i1, etc) - one counter for each array.
In situations like this, I often use the trick of storing the counter in
the zero element of each array. So, you end up with something like:
A[++A[0]] = "something"
gaz...@shell.xmission.com (Kenny McCormack) writes:
I note that your general approach is that you have multiple arrays, running
multiple counters (i, i1, etc) - one counter for each array.
In situations like this, I often use the trick of storing the counter in the zero element of each array. So, you end up with something like:
A[++A[0]] = "something"This should not be necessary. Some languages allow
A[] = "something"
as a way to append to an array, but not AWK. One might think that
A[length(A)] = "something"
would do the trick, but calling length before using A as an array turns
A into a scalar so you get a run-time error when A is indexed.
You can, however, do this:
BEGIN { delete A }
...
A[length(A)] = "something"
which is rather oblique, but works on all the awks I have installed
(gawk, nawk, mawk and original-awk). (You can write 'delete A[0]' if
you don't want to use the newer POSIX syntax.)
--
Ben.
On Friday, August 4, 2023 at 9:53:25 PM UTC+8, Ben Bacarisse wrote:
gaz...@shell.xmission.com (Kenny McCormack) writes:
I note that your general approach is that you have multiple arrays, running >>> multiple counters (i, i1, etc) - one counter for each array.This should not be necessary. Some languages allow
In situations like this, I often use the trick of storing the counter in >>> the zero element of each array. So, you end up with something like:
A[++A[0]] = "something"
A[] = "something"
as a way to append to an array, but not AWK. One might think that
Your first say "but not AWK" here.
A[length(A)] = "something"
would do the trick, but calling length before using A as an array turns
A into a scalar so you get a run-time error when A is indexed.
You can, however, do this:
BEGIN { delete A }
...
A[length(A)] = "something"
which is rather oblique, but works on all the awks I have installed
(gawk, nawk, mawk and original-awk). (You can write 'delete A[0]' if
you don't want to use the newer POSIX syntax.)
Then you say your suggestion is for AWK here.
So, I'm confused on what do you really mean.
--
Ben.
Zhao
Unfortunately I am confused about what is confusing you. I have
obviously not been clear, but I don't know what I need to clarify.
On Friday, August 4, 2023 at 9:53:25 PM UTC+8, Ben Bacarisse wrote:
gaz...@shell.xmission.com (Kenny McCormack) writes:
I note that your general approach is that you have multiple arrays, runningThis should not be necessary. Some languages allow
multiple counters (i, i1, etc) - one counter for each array.
In situations like this, I often use the trick of storing the counter in >> > the zero element of each array. So, you end up with something like:
A[++A[0]] = "something"
A[] = "something"
as a way to append to an array, but not AWK. One might think that
Your first say "but not AWK" here.
A[length(A)] = "something"
would do the trick, but calling length before using A as an array turns
A into a scalar so you get a run-time error when A is indexed.
You can, however, do this:
BEGIN { delete A }
...
A[length(A)] = "something"
which is rather oblique, but works on all the awks I have installed
(gawk, nawk, mawk and original-awk). (You can write 'delete A[0]' if
you don't want to use the newer POSIX syntax.)
Then you say your suggestion is for AWK here.
So, I'm confused on what do you really mean.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 498 |
Nodes: | 16 (2 / 14) |
Uptime: | 53:20:10 |
Calls: | 9,810 |
Calls today: | 12 |
Files: | 13,754 |
Messages: | 6,190,511 |