这段代码有什么问题?

这段代码有什么问题?

代码是;

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

我试图获取 $en 的第七个元素,但输出是;

[7]ergy: -1090.13343774 Ry

$en 数组是 ;

!    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

那么,这段代码有什么问题?为什么输出是这样的?

注:如果所提供的信息不够,请通知我。

答案1

事实是某事可能的bash,并不意味着你应该这样做,或者这是一个好主意。在awk或等语言中,您想要做的事情要容易得多perl

bash 数组是 bash 的一种相当高级的用法,并且由于 bash/sh 语言本身的限制(以及使用它们的尴尬),它并不像其他语言中的数组那么有用。它们非常适合将多个参数传递给命令或函数,但除此之外用途有限。

与其乱搞 bash 数组,不如尝试awk.

例如:

#! /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

输出:

 Energy: -1090.28213580 Ry

嵌入式awk脚本对以 a 开头的每一行进行计数!,当到达第 7 行时,它会打印第 5 个和第 6 个字段。

-F选项将字段分隔符设置为 1 个或多个空白字符(空格、制表符、换行符、回车符、换页符和垂直制表符)。我的评论中使用的版本[\r[:blank:]]+(空白字符、空格和制表符,加上回车符)。对于您的输入数据,它的工作原理是相同的。

如果您的版本awk不支持正则表达式字段分隔符(例如),则只需从命令行中mawk删除。它仍然可以工作,但如果输入文件是 MS-DOS/Windows 文本文件(即使用回车符和换行符作为行结束符)而不是 unix 文本文件(仅使用换行符作为行结束符) ),最后会输出一个回车符。除非通过管道传输,否则回车符将不可见:-F'[[:space:]]+'awkcat -v

 Energy: -1090.28213580 Ry^M

在这种情况下,请先将文件转换为 unix 格式fromdos

答案2

部分问题是您对数组的索引en不正确。当你索引一个数组时,你必须使用大括号;
不是

   $en[$lst]
   ${zh[$lst]}

相关内容