在bash脚本中循环浏览制表符描述的文件


18

这是我到目前为止的内容:

#!/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

和输入文件的示例:

drupal_1    drupal1 tmmjXSWL
drupal_2    drupal2 FHiJSYHM
drupal_3    drupal3 b7bFNj06
drupal_4    drupal4 0AaV62EL

并从脚本输出:

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

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

Answers:


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

我无法告诉您是否有需要解决的问题,还是想知道更多理论上的问题。


谢谢,那行得通。我正在尝试编写一个脚本,以在我正在教的课程的服务器上创建40多个Drupal安装。我有用于设置数据库和文件的脚本,这是将所有内容组合在一起的一部分脚本。我的代码的问题在于$ line在解析时将制表符转换为空格。 $(echo $line | cut -d" " -f1)也可以。
mortona42

如果任何字段包含空格,对我而言将失败
v01pe 2014年

21

问题出在命令中echo $line。由于周围没有引号$line,因此外壳程序对其执行单词拆分,然后将每个单词解释为通配模式。试试看

a='*.txt foo'
ls $a

在您的情况下,制表符使用单独的单词,然后成为的单独参数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

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

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


15
+1。要将IFS设置为bash中的制表符,请执行以下操作:IFS=$'\t'
glenn jackman 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.