【问题标题】:Bash: awk output to arrayBash:awk输出到数组
【发布时间】:2015-12-09 04:50:20
【问题描述】:

我试图将 awk 命令的内容放入 bash 数组中,但遇到了一些麻烦。

>>test.sh
f_checkuser() {
    _l="/etc/login.defs"
    _p="/etc/passwd"
    ## get mini UID limit ##
    l=$(grep "^UID_MIN" $_l)
    ## get max UID limit ##
    l1=$(grep "^UID_MAX" $_l)
    awk -F':' -v "min=${l##UID_MIN}" -v "max=${l1##UID_MAX}" '{ if ( $3 >= min && $3 <= max  && $7 != "/sbin/nologin" ) print $0 }' "$_p"
}
...

使用过的文件:

示例文件:/etc/login.defs

>>/etc/login.defs
### Min/max values for automatic uid selection in useradd
UID_MIN          1000
UID_MAX         60000

示例文件:/etc/passwd

>>/etc/passwd
root:x:0:0:root:/root:/usr/bin/zsh
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
admin:x:1000:1000:Administrator,,,:/home/admin:/bin/bash
daniel:x:1001:1001:Daniel,,,:/home/daniel:/bin/bash

输出如下:

admin:x:1000:1000:Administrator,,,:/home/admin:/bin/bash
daniel:x:1001:1001:User,,,:/home/user:/bin/bash

分别(awk ... print $1 }' "$_p")

admin
daniel

现在我的问题是将 awk 输出保存在一个数组中以将其用作变量。

>>test.sh
...
f_checkuser

echo "Array items and indexes:"
for index in ${!LOKAL_USERS[*]}
do
    printf "%4d: %s\n" $index ${array[$index]}
done

它可能/应该看起来像这个例子。

Array items and indexes:
   0: admin
   1: daniel

特别是,我会成为系统的所有用户(不是 root、bin、sys、ssh、...),而不会在阵列中阻止用户。 也许有人有其他想法来解决我的问题?

【问题讨论】:

  • 发布一些示例输入(/etc/login.defs/etc/passwd 的内容)以及该输入的预期输出。让它成为我们可以测试潜在解决方案的东西。您不需要所有这些 shell 变量和 greps - 只需一个简单的 awk 命令即可。

标签: arrays linux bash shell awk


【解决方案1】:

您是否尝试将一个脚本的输出设置为数组?有一个bash 有办法做到这一点。例如,

a=( $(seq 1 10) ); echo ${a[1]}

将用元素 1 到 10 填充数组 a 并打印 2,第二行由 seq 生成(数组索引从零开始)。只需将 $(...) 的内容替换为您的脚本即可。

【讨论】:

    【解决方案2】:

    对于那些年后来到这里的人......

    bash 4 正是为此目的引入了readarray(又名mapfile)。

    另见Bash capturing output of awk into array

    【讨论】:

      【解决方案3】:

      一个可行的解决方案

      array=()
      f_checkuser(){
              ...
              ...
              tempfile="localuser.tmp"
              touch ${tempfile}
              awk -F':'...'{... print $1 }' "$_p" > ${HOME}/${tempfile}
              getArrayfromFile "${tempfile}"
      }
      getArrayfromFile() {
          i=0
          while read line # Read a line
          do
              array[i]=$line # Put it into the array
              i=$(($i + 1))
          done < $1
      }
      
      f_checkuser
      
      echo "Array items and indexes:"
      for index in ${!array[*]}
      do
          printf "%4d: %s\n" $index ${array[$index]}
      done
      

      输出:

      Array items and indexes:
         0: daniel
         1: admin
      

      但我更喜欢在没有新临时文件的情况下进行观察。 那么,没有临时文件的人还有其他想法吗?

      【讨论】:

      • 我已经告诉过您需要做什么,我们才能为您提供帮助。请重新阅读我之前的评论。
      • 最后一次 - 发布一些我们可以测试可能的解决方案的内容。现在你的输入文件有一堆...s,我确定它们并没有真正存在于你的实际输入文件中,所以去掉它们,你的输出包含user 的行,它不存在你的输入文件。清理它以使其精确和可测试。你在问题上付出的努力越多,别人帮助你回答的机会就越大,而且这个答案是正确的。
      猜你喜欢
      • 1970-01-01
      • 2020-06-24
      • 2020-01-15
      • 2014-09-16
      • 2011-11-18
      • 2011-05-02
      • 2014-08-11
      • 2011-11-03
      • 2019-05-28
      相关资源
      最近更新 更多