这是我到目前为止所拥有的:
#!/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
在命令行中使用时,它会很好地返回令牌。
答案1
问题出在命令上echo $line
。由于 周围没有引号$line
,因此 shell 对其执行分词,然后将每个单词解释为通配模式。尝试一下
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
read
拆分变量值中由字符分隔的字段IFS
,默认情况下由空格和制表符(加上换行符,不能出现在行内)组成。要仅在选项卡上拆分,请先设置IFS
为单个选项卡。请注意,前导和尾随制表符将被忽略,连续的制表符将被视为一个制表符。
read
视为\
特殊字符:反斜杠后跟换行符将被忽略;\\
变成单个反斜杠。如果您想避免这种行为,请传递该-r
选项。
答案2
这个怎么样?
$ 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
我无法判断您是否有问题需要解决,或者想知道更多的理论问题。