Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 为什么我的bashshell脚本在v3.2.5上运行而在4.1.2上失败?_Arrays_Linux_Bash_Shell - Fatal编程技术网

Arrays 为什么我的bashshell脚本在v3.2.5上运行而在4.1.2上失败?

Arrays 为什么我的bashshell脚本在v3.2.5上运行而在4.1.2上失败?,arrays,linux,bash,shell,Arrays,Linux,Bash,Shell,我的bashshell脚本正在bash3.2.5上运行。 我有一个包含以下内容的输入文件: 1234567 2345678 3456789 4567890 以及具有以下代码的bash shell脚本: #!/bin/bash content=($(cat data.txt | awk {'print $1'})) for (( i=0 ; i<${#content[@]} ; i++ )) do if (( i==0 )) then ele=`echo ${content

我的bashshell脚本正在bash3.2.5上运行。 我有一个包含以下内容的输入文件:

1234567
2345678
3456789
4567890
以及具有以下代码的bash shell脚本:

#!/bin/bash
content=($(cat data.txt | awk {'print $1'}))
for (( i=0 ; i<${#content[@]} ; i++ ))
do
  if (( i==0 ))
  then
    ele=`echo ${content[$i]}`
  else
    ele=`echo ","${content[$i]}`
  fi
  all=`echo $all$ele`
done
# should be a string of csv: works on bash 3.2.5 - fails on bash 4.1.2
echo $all
但是当使用bash4.1.2运行时,它会输出:(文件中的最后一个数字;不正确)


为什么Bash 4.1.2中的代码失败了?

使用
echo
设置变量的内容很简单。。错。当我说错的时候,我的意思是,你可以这样做,但是绝对没有理由在这种情况下使用
echo
语句的
命令替换来填充变量。同样,没有理由使用管道连接到
awk
cat
来填充数组。只需一个简单的重定向,填充数组就容易多了

通过消除
echo
piped
命令的所有不必要的
命令替换
,您消除了许多出错的机会。这里有一个可以在3或4上使用的更新

#!/bin/bash
content=( $( <data.txt) )
for (( i=0 ; i<${#content[@]} ; i++ ))
do
    if (( i==0 ))
    then
        ele="${content[i]}"
    else
        ele=",${content[i]}"
    fi
    all="${all}${ele}"
done
echo $all

使用
echo
设置变量的内容很简单。。错。当我说错的时候,我的意思是,你可以这样做,但是绝对没有理由在这种情况下使用
echo
语句的
命令替换来填充变量。同样,没有理由使用管道连接到
awk
cat
来填充数组。只需一个简单的重定向,填充数组就容易多了

通过消除
echo
piped
命令的所有不必要的
命令替换
,您消除了许多出错的机会。这里有一个可以在3或4上使用的更新

#!/bin/bash
content=( $( <data.txt) )
for (( i=0 ; i<${#content[@]} ; i++ ))
do
    if (( i==0 ))
    then
        ele="${content[i]}"
    else
        ele=",${content[i]}"
    fi
    all="${all}${ele}"
done
echo $all

这无助于理解您看到的症状,但您的代码可以完全重写为

paste -d , -s data.txt
如果要使用bash构造,请执行以下操作:

mapfile -t numbers < data.txt   # read the lines of the file into an array
(IFS=,; echo "${numbers[*]}")   # join the array with a comma
mapfile-t numbers

但是,请检查您的数据文件是否不包含回车:
oc-d data.txt
,然后使用
dos2unix
sed-i的/\r$/'data.txt

这无助于理解您看到的症状,但您的代码可以按照以下方式完全重写:

paste -d , -s data.txt
如果要使用bash构造,请执行以下操作:

mapfile -t numbers < data.txt   # read the lines of the file into an array
(IFS=,; echo "${numbers[*]}")   # join the array with a comma
mapfile-t numbers
但是,请检查您的数据文件是否不包含回车:
oc-d data.txt
,并使用
dos2unix
sed-i的/\r$/'data.txt

将显著注释转换为答案

这些作业包括:

ele=`echo ","${content[$i]}"`
all=`echo $all$ele`
不应使用反勾号
`…`
$(…)
命令替换;你应该写得简单些

all="$all$sep${content[$i]}"
其中,您可以在循环之前有
sep=“”
,在分配给所有人之后有
sep=“,”


另外,FWIW,我在Mac OS X 10.10.2上尝试了Bash版本3.2.57(1)和4.3.27(2)的脚本,我得到了与这两个版本相同的正确(预期)输出

  • 你看过bash-xyourscript.sh发生了什么吗?这是一种基本且非常重要的shell脚本调试技术

  • 您是否检查了数据文件中的Windows样式CRLF行尾?

当我的
data.txt
文件有Windows风格的CRLF(回车,换行)行结尾时,我得到了“Bash 4.1.2”输出。当我的
data.txt
文件有Unix风格的NL(换行符,又称换行符)行结尾时,我得到了“Bash 3.2.5”输出


您是否通过Windows系统将材料复制到运行Bash 4.1.2的机器上?或者,换句话说,您确定在测试它的两台机器上运行的数据文件完全相同吗

我会将脚本简化为:

sep=""
all=""
while read number
do
    all="$all$sep$number"
    sep=","
done < data.txt
echo "$all"
sep=“”
all=“”
读数字时
做
all=“$all$sep$number”
sep=“,”
done
还有其他方法可以达到同样的效果,但这是非常直接的,并且不使用任何子shell,这与原始脚本使用大量子shell不同。

将显著的注释转换为答案

这些作业包括:

ele=`echo ","${content[$i]}"`
all=`echo $all$ele`
不应使用反勾号
`…`
$(…)
命令替换;你应该写得简单些

all="$all$sep${content[$i]}"
其中,您可以在循环之前有
sep=“”
,在分配给所有人之后有
sep=“,”


另外,FWIW,我在Mac OS X 10.10.2上尝试了Bash版本3.2.57(1)和4.3.27(2)的脚本,我得到了与这两个版本相同的正确(预期)输出

  • 你看过bash-xyourscript.sh发生了什么吗?这是一种基本且非常重要的shell脚本调试技术

  • 您是否检查了数据文件中的Windows样式CRLF行尾?

当我的
data.txt
文件有Windows风格的CRLF(回车,换行)行结尾时,我得到了“Bash 4.1.2”输出。当我的
data.txt
文件有Unix风格的NL(换行符,又称换行符)行结尾时,我得到了“Bash 3.2.5”输出


您是否通过Windows系统将材料复制到运行Bash 4.1.2的机器上?或者,换句话说,您确定在测试它的两台机器上运行的数据文件完全相同吗

我会将脚本简化为:

sep=""
all=""
while read number
do
    all="$all$sep$number"
    sep=","
done < data.txt
echo "$all"
sep=“”
all=“”
读数字时
做
all=“$all$sep$number”
sep=“,”
done

还有其他方法可以达到同样的效果,但这非常简单,并且不使用任何子shell,这与原始脚本使用大量子shell不同。

这个问题的答案是;由于4.1.2上运行的脚本使用的文件中存在crlf

乔纳森L