Bas komut dosyasında sekme ile belirlenmiş dosyada döngü


18

Şimdiye kadar sahip olduğum şey:

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

Ve girdi dosyasının bir örneği:

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

Ve senaryodan çıktı:

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

Bazı nedenlerden dolayı, her değişken tüm satıra ayarlanır. echo users.txt | cut -f1Komut satırında kullandığımda , jetonu gayet iyi döndürüyor.

Yanıtlar:


6

Buna ne dersin?

$ 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

Çözmeniz gereken bir sorun olup olmadığını veya daha teorik bir konu olup olmadığını merak edemiyorum.


Teşekkürler, işe yarıyor. Öğrettiğim bir sınıf için bir sunucuda 40+ Drupal yüklemesi oluşturmak için bir komut dosyası yazmaya çalışıyorum. Ben DBs ve dosyaları kurmak için komut dosyaları var, bu hepsini bir araya koyacak komut dosyası bir parçasıdır. Kodumdaki sorun, $ satırının ayrıştırıldığı gibi sekmeleri boşluklara dönüştürmesiydi. $(echo $line | cut -d" " -f1)ayrıca çalışır.
mortona42

alanlardan herhangi birinde boşluk varsa benim için başarısız
v01pe

21

Sorun komutta echo $line. Çevresinde tırnak olmadığından $line, kabuk üzerinde kelime bölünmesi gerçekleştirir, ardından her kelimeyi bir globbing paterni olarak yorumlar. İle deneyin

a='*.txt foo'
ls $a

Sizin durumunuzda, sekmeler kelimeleri ayırır ve bu kelimeler daha sonra bağımsız değişkenler haline gelir echo. echoKomut bağımsız değişkenleri arasında bir boşluk basar. Böylece cutsekmeyle ayrılmış alanlar yerine alanla sınırlı alanlar alır.

Değişken ikameleri $foove komut ikamelerinin etrafına her zaman çift tırnak işareti koyun$(foo) (neden onları dışarıda bırakmanız gerektiğini ve bunu yapmanın neden uygun olduğunu anlamadığınız sürece). echo "$line"burada işe yarayacaktır, ancak önerdiğiniz şeyi yapmanın karmaşık bir yoludur.

Kabukta ayrıştırma yaklaşımınızı koruyarak, readkomutun girdiyi alanlara ayrıştırmasını sağlayabilirsiniz.

while read DB USER PASS; do
  echo "DB=$DB USER=$USER PASS=$PASS"
done <users.txt

readalanları IFS, boşluk ve sekmeden (artı satır içinde oluşamayan bir satırsonu) oluşan değişkenin değerinde karakterlerle ayrılmış alanları ayırır . Yalnızca sekmelere bölmek için, IFSönce tek bir sekmeye ayarlayın . Baştaki ve sondaki sekmelerin yok sayıldığını ve ardışık sekmelerin tek bir sekme olarak sayıldığını unutmayın.

read\özel bir karakter gibi davranır : ters eğik çizgi ve ardından bir yeni satır göz ardı edilir; \\tek ters eğik çizgi haline gelir. Bu davranışı önlemek istiyorsanız, -rseçeneği iletin.


15
+1. IFS'yi bash'da bir sekme karakterine ayarlamak için:IFS=$'\t'
glenn jackman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.