วนรอบไฟล์ที่คั่นด้วยแท็บในสคริปต์ทุบตี


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

ฉันไม่สามารถบอกได้ว่าคุณมีปัญหาในการแก้หรือสงสัยเกี่ยวกับประเด็นทางทฤษฎีมากกว่านี้หรือไม่


ขอบคุณที่ใช้งานได้ ฉันพยายามเขียนสคริปต์เพื่อสร้างการติดตั้ง Drupal มากกว่า 40+ ครั้งบนเซิร์ฟเวอร์สำหรับชั้นเรียนที่ฉันกำลังสอน ฉันมีสคริปต์เพื่อตั้งค่าฐานข้อมูลและไฟล์นี่เป็นส่วนหนึ่งของสคริปต์ที่จะรวมเข้าด้วยกัน ปัญหาเกี่ยวกับรหัสของฉันคือการที่ $ 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

readแยกฟิลด์ที่คั่นด้วยอักขระในค่าของIFSตัวแปรซึ่งประกอบด้วยช่องว่างและแท็บ (รวมถึงการขึ้นบรรทัดใหม่ซึ่งไม่สามารถเกิดขึ้นภายในบรรทัด) โดยค่าเริ่มต้น หากต้องการแยกเฉพาะที่แท็บให้ตั้งค่าIFSเป็นแท็บเดียวก่อน โปรดทราบว่าแท็บนำหน้าและต่อท้ายจะถูกละเว้นและแท็บที่ต่อเนื่องจะนับเป็นแท็บเดียว

readถือว่า\เป็นอักขระพิเศษ: เครื่องหมายแบ็กสแลชตามด้วยบรรทัดใหม่จะถูกละเว้น \\กลายเป็นแบ็กสแลชเดี่ยว หากคุณต้องการหลีกเลี่ยงพฤติกรรมนี้ให้ผ่าน-rตัวเลือก


15
+1 ในการตั้งค่า IFS ให้เป็น char tab ใน bash:IFS=$'\t'
glenn jackman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.