(bash)系统地将更改应用于变量数组的最不冗余的方法是什么



我的目标是检查以"/"结尾的文件路径列表,如果是这样,则将其删除。

理想情况下,我希望更改原始的FILEPATH变量以反映这种更改,并且我希望这能在没有不必要的冗余的情况下用于长列表。我试着把它作为一个循环来做,但这些变化并没有改变原始变量,只是改变了迭代的"EACH_PATH"变量。有人能想出更好的方法吗?

这是我的代码:

FILEPATH1="filepath1/file1"
FILEPATH2="filepath2/file2/"
PATH_ARRAY=(${FILEPATH1} ${FILEPATH2})
echo ${PATH_ARRAY[@]}
for EACH_PATH in ${PATH_ARRAY[@]}
do
if [ "${EACH_PATH:$((${#EACH_PATH}-1)):${#EACH_PATH}}"=="/" ]
then EACH_PATH=${EACH_PATH:0:$((${#EACH_PATH}-1))}
fi
done

edit:我很高兴用一种完全不同的方式来做这件事,并删除上面的代码,我只想知道最优雅的方法。

我并不完全清楚这里的实际目标,但根据情况,我可以看到几种可能的解决方案。最好的(如果它能在这种情况下工作的话(是省去单个变量,只使用数组条目。例如,您可以使用:

declare -a filepath
filepath[1]="filepath1/file1"
filepath[2]="filepath2/file2/"
for index in "${!filepath[@]}"; do
if [[ "${filepath[index]}" = *?/ ]]; then
filepath[index]="${filepath[index]%/}"
fi
done

然后始终使用CCD_ 1而不是CCD_。一些注意事项:

  • 我使用了小写名称。通常最好避免使用所有大写名称,因为有很多大写名称具有特殊功能,意外使用其中一个名称可能会造成麻烦
  • "${!filepath[@]}"获取数组的索引的列表(在本例中为"1"2"(,而不是它们的值;这是必要的,这样我们就可以设置条目,而不仅仅是查看它们
  • 我更改了斜杠修剪测试的逻辑——它使用[[ = ]]进行模式匹配,查看条目是否以"/"结尾,并且在此之前是否至少有一个字符(即它不是,只是"/",因为您不想修剪它(。然后,它在扩展%/中使用,仅从值的末尾修剪"/">

如果数字索引数组不起作用(并且您至少有bash版本4(,那么字符串索引("关联"(数组如何?它非常相似,但对索引中的变量使用declare -A$(通常引用它们(。类似这样的东西:

declare -A filepath
filepath["foo"]="filepath1/file1"
filepath["bar"]="filepath2/file2/"
for index in "${!filepath[@]}"; do
if [[ "${filepath["$index"]}" = *?/ ]]; then
filepath["$index"]="${filepath["$index"]%/}"
fi
done

如果确实需要单独的变量而不是数组项,则可以使用变量名称和间接变量引用的数组。它的工作方式在不同的shell之间有很大的差异,根据数据中的内容(在本例中,特别是path_array中的内容(,它很容易是不安全的。以下是在bash中执行此操作的方法:

filepath1="filepath1/file1"
filepath2="filepath2/file2/"
path_array=(filepath1 filepath2)
for varname in "${path_array[@]}"; do
if [[ "${!varname}" = *?/ ]]; then
declare "$varname=${!varname%/}"
fi
done

使用sed

PATH_ARRAY=($(echo ${PATH_ARRAY[@]} | sed 's#/ ##g;s#/$##g'))

演示:

$FILEPATH1="filepath1/file1"
$FILEPATH2="filepath2/file2/"
$PATH_ARRAY=(${FILEPATH1} ${FILEPATH2})
$echo ${PATH_ARRAY[@]}
filepath1/file1 filepath2/file2/
$PATH_ARRAY=($(echo ${PATH_ARRAY[@]} | sed 's#/ ##g;s#/$##g'))
$echo ${PATH_ARRAY[@]}
filepath1/file1 filepath2/file2
$

最新更新