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コマンドラインで使用すると、トークンが正常に返されます。

回答:


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インストールを作成するスクリプトを作成しようとしています。DBとファイルをセットアップするスクリプトがありますが、これはすべてをまとめるスクリプトの一部です。私のコードの問題は、$ lineが解析時にタブをスペースに変換することでした。 $(echo $line | cut -d" " -f1)動作します。
mortona42

フィールドのいずれかにスペースが含まれている場合は、私のために失敗した
v01pe

21

問題はコマンドにありecho $lineます。の周り$lineに引用符がないため、シェルはその上で単語分割を実行し、各単語をグロビングパターンとして解釈します。で試してみてください

a='*.txt foo'
ls $a

あなたの場合、タブは単語を分離し、単語はの別個の引数になりechoます。echoコマンドは、スペースで区切られた引数を出力します。そのcutため、タブ区切りフィールドではなくスペース区切りフィールドを受け取ることになります。

常に変数の置換$fooとコマンドの置換を二重引用符で囲みます$(foo)(それらを除外する必要がある理由とそうする必要がある理由を理解していない限り)。echo "$line"ここで動作しますが、提案したことを行うのは複雑な方法です。

シェルで構文解析のアプローチを維持したまま、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'
グレンジャックマン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.