忽略bash索引数组的空元素

时间:2013-11-08 18:10:25

标签: arrays bash

我正在过滤PATH个变量,以便删除某些元素(在下面的例子中,它的元素包含字符串x86;实际上我正在寻找字符串{{1} }):

site-packages

这很有效,除了所有被清零的元素仍然存在,但是空的。我想最终消除这些元素,我不想使用除bash之外的任何东西(我知道我可以使用$ echo $(IFS=:;arr=($PATH);echo "${arr[*]//*x86*}") /usr/local/bin:/usr/bin:/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live::/cygdrive/c/Program Files/Lenovo Fingerprint Reader:::/cygdrive/c/Program Files/Intel/iCLS Client:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/DAL:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/IPT:::::/cygdrive/c/Program Files/Intel/WiFi/bin:/cygdrive/c/Program Files/Common Files/Intel/WirelessCommon:/cygdrive/c/Program Files/Common Files/Lenovo:::/cygdrive/c/SWTOOLS/ReadyApps:::::/usr/lib/lapack ,但出于便携性原因,我强烈希望使用bash-只有解决方案)。

这是基于tr的解决方案:

tr

更新:我正在使用数组,因为我想在路径元素中面对空格(或冒号以外的任何其他东西)时保持健壮。

4 个答案:

答案 0 :(得分:3)

你必须更加明确:

PATH=$(
  IFS=:
  new=()
  for p in $PATH; do
    [[ $p != *x86* ]] && new+=("$p")
  done
  echo "${new[*]}"
)

它更详细,但正确且仅按要求bash

答案 1 :(得分:2)

这不需要显式循环,但可能有点脆弱。它使用退格键来" unwrite"要删除的目录前面的冒号,如果PATH中的第一个或最后一个目录被删除,则需要进行特殊处理。

echo $(IFS=:;
       arr=($PATH);
       # When finally echoed, any \b character will remove
       # the preceding colon from the output.
       new="${arr[*]//*x86*/$'\b'}";
       # Remove :\b if last directory was removed
       new=${new%:$'\b'};
       # Remove \b: if first directory was removed
       echo "${new#$'\b':}")

答案 2 :(得分:0)

这是一个使用循环构建连续数组的版本:

$ echo $(IFS=:;arr=($PATH);sqarr="${arr[*]//*x86*}";declare -a finalarr; for item in $sqarr; do [[ $item ]] && finalarr+=("$item"); done; echo "${finalarr[*]}")
/usr/local/bin:/usr/bin:/cygdrive/c/Program Files/Common Files/Microsoft Shared/Windows Live:/cygdrive/c/Program Files/Lenovo Fingerprint Reader:/cygdrive/c/Program Files/Intel/iCLS Client:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/DAL:/cygdrive/c/Program Files/Intel/Intel(R) Management Engine Components/IPT:/cygdrive/c/Program Files/Intel/WiFi/bin:/cygdrive/c/Program Files/Common Files/Intel/WirelessCommon:/cygdrive/c/Program Files/Common Files/Lenovo:/cygdrive/c/SWTOOLS/ReadyApps:/usr/lib/lapack

跨多行:

$(
  IFS=:
  arr=($PATH)
  sqarr="${arr[*]//*x86*}"
  declare -a finalarr
  for item in $sqarr; do 
      [[ $item ]] && finalarr+=("$item")
  done 
  echo "${finalarr[*]}"
)

答案 3 :(得分:0)

这应该与一起使用,假设PATH成分不包含空格,所以肯定比其他解决方案更脆弱。空数组元素在arr2赋值

处被丢弃
echo $(IFS=:;arr=($PATH);unset IFS;arr2=(${arr[@]//*x86*});IFS=:;echo "${arr2[*]}")