循环遍历bash脚本中的制表符描述文件

mor*_*a42 19 bash

这是我到目前为止所拥有的:

#!/bin/bash
while read line; do
        DB=$(echo $line | cut -f1)
        USER=$(echo $line | cut -f2)
        PASS=$(echo $line | cut -f3)
        echo DB=$DB USER=$USER PASS=$PASS
done < users.txt
Run Code Online (Sandbox Code Playgroud)

以及输入文件的示例:

drupal_1    drupal1 tmmjXSWL
drupal_2    drupal2 FHiJSYHM
drupal_3    drupal3 b7bFNj06
drupal_4    drupal4 0AaV62EL
Run Code Online (Sandbox Code Playgroud)

以及脚本的输出:

DB=drupal_1 drupal1 tmmjXSWL USER=drupal_1 drupal1 tmmjXSWL PASS=drupal_1 drupal1 tmmjXSWL
DB=drupal_2 drupal2 FHiJSYHM USER=drupal_2 drupal2 FHiJSYHM PASS=drupal_2 drupal2 FHiJSYHM
DB=drupal_3 drupal3 b7bFNj06 USER=drupal_3 drupal3 b7bFNj06 PASS=drupal_3 drupal3 b7bFNj06
Run Code Online (Sandbox Code Playgroud)

出于某种原因,每个变量都设置为整行。当我echo users.txt | cut -f1在命令行使用时,它返回令牌就好了。

Gil*_*il' 23

问题出在命令中echo $line。由于 周围没有引号$line,shell 对其进行分词,然后将每个词解释为通配模式。试试看

a='*.txt foo'
ls $a
Run Code Online (Sandbox Code Playgroud)

在您的情况下,选项卡将单词分开,然后成为echo. 该echo命令打印由空格分隔的参数。所以cut最终会收到空格分隔的字段而不是制表符分隔的字段。

始终在变量替换$foo和命令替换周围放置双引号$(foo)(除非您明白为什么需要将它们排除在外以及为什么可以这样做)。echo "$line"会在这里工作,但这是一种复杂的方式来执行您的建议。

保持在 shell 中解析的方法,您可以使read命令将输入​​解析为字段。

while read DB USER PASS; do
  echo "DB=$DB USER=$USER PASS=$PASS"
done <users.txt
Run Code Online (Sandbox Code Playgroud)

read拆分由IFS变量值中的字符分隔的字段,默认情况下由一个空格和一个制表符(加上一个换行符,不能出现在一行内)组成。要仅在选项卡处拆分,IFS请先设置为单个选项卡。请注意,前导和尾随制表符将被忽略,连续的制表符计为一个。

read视为\特殊字符:忽略反斜杠后跟换行符;\\变成一个反斜杠。如果您想避免这种行为,请传递该-r选项。

  • +1。在 bash 中将 IFS 设置为制表符:`IFS=$'\t'` (17认同)

bah*_*mat 6

这个怎么样?

$ awk '{print "DB="$1"\tUSER="$2"\tPASS="$3}' users.txt
DB=drupal_1 USER=drupal1    PASS=tmmjXSWL
DB=drupal_2 USER=drupal2    PASS=FHiJSYHM
DB=drupal_3 USER=drupal3    PASS=b7bFNj06
DB=drupal_4 USER=drupal4    PASS=0AaV62EL
Run Code Online (Sandbox Code Playgroud)

我不知道您是否有问题要解决,或者想知道更理论化的问题。