在bash内剪切/回显

Cut / echo inside bash

我对以下剪辑在 bash 脚本中的工作方式感到困惑。

file.csv 样本:

#10.10.10.10;28;9.10.10.10: up;Something ;More random spaces

我的脚本:

#!/bin/bash

csv_file="file.csv"

locations=( $( cut -d';' -f5 $csv_file ) )

for ((i=0; i < ${#locations[@]}; i++))
do
   echo "${locations[$i]}"
done

脚本的结果是:

More
random
spaces

当我只是在我的 CLI 中复制并粘贴剪辑时,没有任何回声或变量,剪辑按我预期的方式工作并打印:

More random spaces

我确定是括号或引号问题,但我就是想不通。

以下语句创建一个包含三个元素的数组:

location=(More random spaces)

你的command substitution $(...) undergo's word splitting and pathname expansion

a="hello world"
arr=($(echo "$a")); # Bad example, as it could have been: arr=($a)

echo "${arr[0]}" # hello
echo "${arr[1]}" # world

您可以通过将命令替换用双引号括起来来防止这种情况发生:

arr=( "$(...)" )
echo "${arr[0]}" # hello world

同样适用于parameter expansions,例如:

a="hello world"
printf "<%s>" $a   # <hello><world>
printf "<%s>" "$a" # <hello world>

需要在位置数组中引用子shell命令:

locations=( "$( cut -d';' -f5 $csv_file )" )

有关此事的更多信息 "arrays with spaces" 此处:BASH array with spaces in elements

您的 cut 命令给出字符串 More random spaces,当您将其转换为数组时,它有 3 个字段。

您可以将脚本更改为

cut -d";" -f5 < ${csv_file}

当您想对每一行输出做更多的事情时,您可以使用

进行更多控制
csv_file="file.csv"

while IFS=";" read -r f1 f2 f3 f4 f5 f6_and_higher; do
   # Ignore fields f1 f2 f3 and f4
   echo "${f5}"
done < ${csv_file}

或者(更好)您可以使用

避免 while 循环
awk -F ";" '{print }' ${csv_file}