【问题标题】:How to use Internal Field Separator correctly?如何正确使用内部字段分隔符?
【发布时间】:2022-10-15 01:37:01
【问题描述】:

我正在尝试将 IFS 设置为“:”,但它似乎不起作用。这是我的代码,

FILE="/etc/passwd"

while IFS=':' read -r line; do
        set $line
        echo $1
done < $FILE

当我运行我的代码时,它似乎给了我整行。我使用 set 命令分配位置参数,仅提取用户名,但是当我尝试打印第一个位置参数 $1 时,它会输出整行。我究竟做错了什么?

【问题讨论】:

  • while IFS=: read -r user_name _; do printf '%s\n' "$user_name"; done &lt;/etc/passwd
  • @Jetchisel 你能解释一下你的答案吗?我是 bash 编程的新手。还有为什么我不能使用set
  • while IFS=: read -ra gecos_field; do printf '%s\n' "${gecos_field[0]}"; done &lt;/etc/passwd
  • @Jetchisel我想提取除用户名以外的其他信息,例如组ID和用户ID。 set 不是更合适吗?
  • bash 中的 read 内置有 a 标志,它将输入放入数组中

标签: bash ifs


【解决方案1】:

您仅为read 命令设置IFS。当您展开 $line 变量时,它会被设置回原始值。您需要在此处设置IFS,而不是在阅读时设置。

oldIFS="$IFS" # save IFS
IFS=:

while read -r line; do
    set $line
    echo $1
done < $FILE

IFS="$oldIFS" # restore original IFS

【讨论】:

  • 什么是旧IFS?为什么将其设置为 IFS 并将其重置回 IFS?我是 bash 编程的新手。
  • 我正在保存它,以便IFS 在循环完成后恢复到其原始值。
  • 为什么?我的意思是我希望它一直是':'?为什么我需要将其设置回原来的值?
【解决方案2】:
  • IFS=':' read -r line 读取整行
  • IFS=':' read -r name remainder 将第一个字段放入变量 name 中,并将该行的其余部分放入 remainder
  • IFS=':' read -r name password remainder 将第一个字段放入变量 name 中,将第二个字段放入变量 password 中,并将该行的其余部分放入 remainder 中。
  • 等...

在 bash 中,您可以使用 read -a array_var 获取包含所有字段的数组,这可能是您的目的最简单的解决方案:

#!/bin/bash

while IFS=':' read -r -a fields
do
    echo "${fields[0]}"
done < /etc/passwd

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    相关资源
    最近更新 更多