สร้างไฟล์ใหม่ที่มีโครงสร้างเฉพาะจากไฟล์ข้อความ


0

บน Linux orig-file.txtฉันมีไฟล์ ไฟล์นี้มี 4 ฟิลด์ในขณะนี้ แต่อาจน้อยกว่านี้ (ไฟล์นี้สร้างโดยแอปพลิเคชันอื่น)

ตัวเลือกที่ดีที่สุดในการแปลorig-file.txtไฟล์เป็นไฟล์เช่นอะไรoutput-file.txt(อาจเป็นได้ด้วยเชลล์สคริปต์หรือ awk เป็นต้น)

orig-file.txt

CREATE_TIMESTAMP              TELEPHONE_NUMBER             ID TYPE
-------------------           -------------------- ---------- -----------------
24-09-2009 16:17:45           33633333333                  20 other_mmm_phone
24-09-2009 17:45:07           33644444444                  20 other_mmm_phone
07-10-2009 10:45:49           12312312312                  20 legacyphone
07-10-2009 11:46:38           59320000043                  20 other_mmm_phone

ผลผลิต file.txt

CREATE_TIMESTAMP -> 24-09-2009 16:17:45
TELEPHONE_NUMBER -> 33633333333
ID               -> 20
TYPE             -> other_mmm_phone



---



CREATE_TIMESTAMP -> 24-09-2009 16:17:45
TELEPHONE_NUMBER -> 33633333333
ID               -> 20
TYPE             -> other_mmm_phone

---

ตัวอย่างจาก awk lang - (แต่มันไม่ทำงาน - :(

# awk 'NR>2 {
 > printf "\
 > %-16s -> %s\n\
 > %-16s -> %s\n\
 > %-16s -> %s\n\
 > %-16s -> %s\
 > \n\n\n---\n\n\n",\
 >         "CREATE_TIMESTAMP", $1" "$2,\
 >         "TELEPHONE_NUMBER", $3,\
 >         "ID", $4,\
 >         "TYPE", $5}\
 > '   orig-file.txt
awk: newline in string near line 2
awk: syntax error near line 3
awk: illegal statement near line 3
awk: newline in string near line 7

ไม่ว่าไฟล์ดั้งเดิมหรือไฟล์เอาต์พุตของคุณจะเป็น CSV ที่นี่
slhck

ตกลงดูการอัปเดตของฉัน (ฉันลบคำ CSV) คุณไม่ใช่ CSV แต่ไฟล์อื่น ๆ ที่มีโครงสร้างเฉพาะ
yael

ฮึ่ม ฉันขอโทษที่เลือกคำเหล่านี้ แต่นี่เป็นโครงสร้างไฟล์ที่โง่ที่จะจัดการ ถ้ามันเป็นไฟล์ CSV มันจะง่ายสุด ๆ แต่นี่มันเป็นไปไม่ได้ที่จะแยกวิเคราะห์ คุณไม่สามารถรับข้อมูลในรูปแบบอื่นได้หรือไม่
slhck

ใครคือไฟล์ที่โง่ - orig-file.txt หรือ output-file.txt - ความแออัดของคุณคืออะไร? โปรดยกตัวอย่างอื่น ๆ ให้ฉันในรูปแบบที่ดีที่สุดที่ฉันสามารถรับได้จากไฟล์ orig-file.txt
yael

1
output-file.txtเป็นรูปแบบที่ไม่ดีในสายตาของฉัน มีความชัดเจนน้อยกว่าในการอ่านด้วยตนเองมากกว่าorig-file.txtimho
Daniel Andersson

คำตอบ:


0

นี่คือ ksh ธรรมดา:

{
  read t1 t2 t3 t4
  maxlen=$(printf "%s\n" ${#t1} ${#t2} ${#t3} ${#t4} | sort -n | tail -1)
  fmt=$(printf "%%-%ds -> %%s" $maxlen)
  read line
  while read date time tel id type; do
    printf "$fmt\n" $t1 "$date $time" $t2 $tel $t3 $id $t4 $type
    print "\n\n\n---\n\n"
  done
} < orig-file.txt

อัปเดตสำหรับจำนวนฟิลด์ที่ยืดหยุ่น:

ฉันแทนที่พื้นที่ในเขตข้อมูลวันที่และเวลาเพื่อทำให้การแยกวิเคราะห์ง่ายขึ้น

sed '3,$s/ /@@/' orig-file.txt | 
{
    read line
    set -A headings $line
    max=0
    for head in "${headings[@]}"; do (( max < ${#head} )) && max=${#head}; done
    fmt=$(printf "%%-%ds -> %%s" $max)

    read line

    while read line; do
        set -A fields $line
        i=0
        while (( i < ${#headings[@]} )); do
            printf "$fmt\n" ${headings[$i]} ${fields[$i]} | sed 's/@@/ /'
            (( i=i+1 ))
        done
        print "\n\n\n---\n\n"
    done
}

ตกลงเจ๋งมาก - แต่สิ่งที่ฉันจะทำถ้าไฟล์ของฉันจะมี 5 หรือ 6 สาขาและไม่ใช่ 4 - เราสามารถสร้างไวยากรณ์ที่ยืดหยุ่นได้หรือไม่? ที่รองรับฟิลด์จำนวนเท่าใดก็ได้ ??? (ตัวอย่างเช่นฉันมีพารามิเตอร์ที่กำหนดจำนวนฟิลด์ - NUM_OF_FIELDS)
yael

ตัวอย่างเช่น [[$ NUM_OF_FIELDS -eq 4]] && อ่าน t1 t2 t3 t4 หรือ [[$ NUM_OF_FIELDS -eq 5]] && อ่าน t1 t2 t3 t4 t5 ... ฯลฯ
yael

@yael อัปเดตเพื่อใช้อาร์เรย์
เกล็นแจ็คแมน

0

นี่จะทำงานในกรณีนี้ จำเป็นต้องปรับเปลี่ยนเล็กน้อยหากมีการเพิ่มฟิลด์เพิ่มเติม

awk 'NR>2{
    printf "\
%-16s -> %s\n\
%-16s -> %s\n\
%-16s -> %s\n\
%-16s -> %s\
\n\n\n---\n\n\n",\
        "CREATE_TIMESTAMP", $1" "$2,\
        "TELEPHONE_NUMBER", $3,\
        "ID", $4,\
        "TYPE", $5}\
' orig-file.txt > output-file.txt

"CREATE_TIMESTAMP" ต้องการทั้งคู่$1และ$2เนื่องจากวันที่นั้นแยกจากกันด้วยช่องว่าง


มันสามารถแก้ไขได้เพื่ออ่านชื่อฟิลด์จากส่วนหัว แต่มีปัญหากับวันที่คั่นด้วยช่องว่าง หากเขตข้อมูลอื่นได้รับอนุญาตให้มีช่องว่างการแก้ไขด้วยตนเองจะต้องมีการชดเชยเสมอเช่นใน$1" "$2กรณี


แต่วิธีการสร้าง awk นี้ในสคริปต์ ksh ของฉันได้อย่างไร สองสิ่งที่ฉันต้องเพิ่มในกรณีที่เรามีห้าฟิลด์ขึ้นไป?
yael

1
@ Yael: เช่นเดียวกับที่คุณทำกับเครื่องมืออื่น ๆ ไพพ์หรือให้มันอ่านจากไฟล์ temp และอื่น ๆ นี่ไม่ได้อยู่ในขอบเขตคำถามปัจจุบันของคุณ
Daniel Andersson

ok แต่เห็นการปรับปรุงของฉัน awk ไม่ทำงานบน ksh shell?
yael

@yael: ฉันใช้แบ็กสแลชที่ท้ายบรรทัดเพื่อให้สามารถเขียนบรรทัดด้านล่างต่อไปเพื่อความชัดเจนในการนำเสนอ เพียงลบแบ็กสแลชทั้งหมดที่บรรทัดสุดท้ายจากนั้นลบตัวแบ่งบรรทัดทั้งหมดเพื่อเขียนคำสั่งทั้งหมดในบรรทัดเดียว สิ่งนี้ควรทำงานในระดับสากล
Daniel Andersson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.