-3

The code is ;

cm=$1
nm=$2
case $cm in
"out")
declare -a  en
declare -a inf
ec=$(grep -n "! " hw1_out_si_wire.txt)
IFS=$'\n' en=($ec)
lst=$((${#en[@]} -1))
IFS=' ' inf=($en[$lst])
echo " Energy: ${inf[4]} ${inf[5]}"
;;
"in") echo "It's not my problem";;
esac

And I'm trying to take 7th element of $en but the output is ;

[7]ergy: -1090.13343774 Ry

And the $en array is ;

!    total energy              = -1090.13343774 Ry
!    total energy              = -1090.20757070 Ry
!    total energy              = -1090.24296462 Ry
!    total energy              = -1090.25563488 Ry
!    total energy              = -1090.27085564 Ry
!    total energy              = -1090.27693129 Ry
!    total energy              = -1090.28213580 Ry
!    total energy              = -1090.29131927 Ry

So, what is the problem with this code ?Why is the output like this ?

Note:If the informations given is not enough , please inform me.

closed as off-topic by cas, Scott, Anthon, Stephen Kitt, dr01 Jun 4 '16 at 17:42

  • This question does not appear to be about Unix or Linux within the scope defined in the help center.
If this question can be reworded to fit the rules in the help center, please edit the question.

  • Could the person who voted against say the reason for it ? – onurcanbektas Jun 3 '16 at 9:55
  • 2
    Whenever I see things like [7]tring when I'm expecting somestring [7] I suspect Windows-style CR-LF line-endings are involved – steeldriver Jun 3 '16 at 11:20
  • 1
    Your input file probably has DOS-style line endings. dos2unix it. – Mat Jun 3 '16 at 11:41
  • 3
    I'm voting to close this question as off-topic because it belongs on codereview.stackexchange.com – cas Jun 4 '16 at 4:27
  • 1
    e.g. awk -F'[\r ]+' '/^!/ {c++} ; c==7 { print " Energy:",$5,$6 }' hw1_out_si_wire.txt - this works whether it's a dos text file or unix format. – cas Jun 4 '16 at 10:44
0

The fact that something is possible to do in bash, doesn't mean that you should, or that it's a good idea. What you are trying to do is much easier in languages like awk or perl.

bash arrays are a fairly advanced usage of bash and, due to limitations in the bash/sh language itself (and the awkwardness of using them), not really as useful as arrays are in other languages. They're great for passing multiple arguments to a command or a function, but of limited use beyond that.

Instead of messing around with bash arrays, try awk.

For example:

#! /bin/sh

cm="$1"
nm="$2"

case "$cm" in
  out) awk -F'[[:space:]]+' '
           /^!/  {
             c++;
             if (c==7) {
               print " Energy:",$5,$6;
             };
           };' hw1_out_si_wire.txt ;;

   in) echo "It's not my problem" ;;
esac

Output:

 Energy: -1090.28213580 Ry

The embedded awk script counts each line beginning with a !, and when it gets to the 7th line, it prints the 5th and 6th fields.

The -F option sets the field separator to 1-or-more whitespace characters (spaces, tabs, newlines, carriage returns, form-feeds, and vertical tabs). The version in my comment used [\r[:blank:]]+ (which is blank characters, spaces and tabs, plus carriage-return). For your input data, it works the same.

If your version of awk doesn't support regexp field-separators (e.g. mawk) then just drop the -F'[[:space:]]+' from the awk command-line. It will still work, but if the input file is a MS-DOS/Windows text file (i.e. with carriage-return and line-feed as line-ending) rather than a unix text file (with line-feed only as line-ending), it'll output a carriage-return at the end. The carriage-return will be invisible unless piped through cat -v:

 Energy: -1090.28213580 Ry^M

In that case, convert the file to unix format with fromdos first.

  • @leth try the script now, i fixed a bug where it would print all lines it sees while c==7, not just those matching /^!/. Again, remove the -F'[[:space:]]+' option from the awk command line if your awk doesn't support it. – cas Jun 4 '16 at 23:39
0

Part of the problem is that you're indexing into the en array incorrectly.  When you index into an array, you have to use braces;
not

   $en[$lst]
but
   ${en[$lst]}

  • the last element of $en is the first [0] element of $inf this time. – onurcanbektas Jun 4 '16 at 6:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.