代码是;
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:]]+'
awk
cat -v
Energy: -1090.28213580 Ry^M
在这种情况下,请先将文件转换为 unix 格式fromdos
。
答案2
部分问题是您对数组的索引en
不正确。当你索引一个数组时,你必须使用大括号;
不是
$en[$lst]但
${zh[$lst]}