รวมไฟล์ข้อความที่ชาญฉลาดคอลัมน์


52

ฉันมีไฟล์ข้อความสองไฟล์ คนแรกมีเนื้อหา:

Languages
Recursively enumerable
Regular

ในขณะที่สองมีเนื้อหา:

Minimal automaton
Turing machine
Finite

ฉันต้องการรวมไว้ในหนึ่งคอลัมน์ที่ชาญฉลาด ดังนั้นฉันจึงพยายามpaste 1 2และผลลัพธ์คือ:

Languages   Minimal automaton
Recursively enumerable  Turing machine
Regular Finite

อย่างไรก็ตามฉันต้องการให้คอลัมน์อยู่ในแนวเดียวกันเช่น

Languages               Minimal automaton
Recursively enumerable  Turing machine
Regular                 Finite

ฉันสงสัยว่ามันจะเป็นไปได้ไหมหากไม่ได้จัดการด้วยตนเอง?


ที่เพิ่ม:

นี่เป็นอีกตัวอย่างหนึ่งที่ Bruce ใช้วิธีเกือบจะจับมันยกเว้นบางแนวที่ฉันสงสัยว่าทำไม

$ cat 1
Chomsky hierarchy
Type-0
—

$ cat 2
Grammars
Unrestricted

$ paste 1 2 | pr -t -e20
Chomsky hierarchy   Grammars
Type-0              Unrestricted
—                    (no common name)

3
ตัวอย่างสุดท้ายนั่นคือการเยื้องแนว ฉันสามารถทำซ้ำใน Arch linux, pr (GNU coreutils) 8.12 ฉันไม่สามารถทำสำเนาบน Slackware ผู้สูงอายุ (11.0) ฉันยังมี: pr (GNU coreutils) 5.97 ปัญหาเกิดจากตัวอักษร '-' และอยู่ในขั้นต้นไม่ใช่วาง
Bruce Ediger

1
ฉันได้รับสิ่งเดียวกันกับ EM-DASH ทั้งสองprและexpand... columnsหลีกเลี่ยงปัญหานี้
Peter.O

ฉันสร้างเอาต์พุตสำหรับคำตอบที่แตกต่างกันส่วนใหญ่ยกเว้นawk + pasteซึ่งจะเปลี่ยนเป็นคอลัมน์ขวาสุดถ้าไฟล์ซ้ายสั้นกว่าทางขวาของมัน เหมือนกันและอื่น ๆ ใช้กับ'วาง + คอลัมน์'ซึ่งยังมีปัญหานี้กับบรรทัดว่างในคอลัมน์ซ้าย ... หากคุณต้องการที่จะเห็นผลลัพธ์ทั้งหมดเข้าด้วยกัน นี่คือลิงค์: paste.ubuntu.com/643692ฉันใช้ 4 คอลัมน์แล้ว
Peter.O

ผมเพิ่งสังเกตเห็นบางสิ่งบางอย่างที่ทำให้เข้าใจผิดในpaste.ubuntuลิงก์ ... ฉันเดิมตั้งค่าข้อมูลขึ้นสำหรับการทดสอบสคริปต์ของฉัน (และที่นำไปทำคนอื่น ๆ ) ... ดังนั้นสาขาที่กล่าวว่า➀ unicode may render oddly but the column count is ok แน่นอนไม่ได้นำไปใช้wc-paste-prและwc-paste-prพวกเขา แสดงความแตกต่างในการนับคอลัมน์ .. ส่วนอื่น ๆ ก็โอเค
Peter.O

1
@BruceEdiger: ปัญหาการจัดตำแหน่งเกิดขึ้นเมื่อมีการใช้อักขระที่ไม่ใช่ ASCII (ในคำถามของเขา OP ใช้เครื่องหมายขีด (-) แทนอักขระลบ (-)) ส่วนใหญ่อาจเกิดจากการไม่ถูกต้องหรือไม่มีการจัดการโดยprมัลติไบต์ อักขระในโลแคลปัจจุบัน (ปกติคือ UTF8)
WhiteWinterWolf

คำตอบ:


68

คุณเพียงแค่ต้องใช้columnคำสั่งและบอกให้ใช้แท็บเพื่อแยกคอลัมน์

paste file1 file2 | column -s $'\t' -t

ในการแก้ไขข้อพิพาท "เซลล์ว่าง" เราเพียงต้องการ-nตัวเลือกเพื่อcolumn:

$ paste <(echo foo; echo; echo barbarbar) <(seq 3) | column -s $'\t' -t
foo        1
2
barbarbar  3

$ paste <(echo foo; echo; echo barbarbar) <(seq 3) | column -s $'\t' -tn
foo        1
           2
barbarbar  3

หน้าคอลัมน์คนของฉันระบุว่า-nเป็น "ส่วนขยาย Debian GNU / Linux" ระบบ Fedora ของฉันไม่พบปัญหาเซลล์ว่างเปล่า: ดูเหมือนว่าจะมาจาก BSD และหน้าคนบอกว่า "เวอร์ชั่น 2.23 เปลี่ยนแปลงตัวเลือก -s เป็นไม่โลภ"


4
glenn: คุณคือฮีโร่ของชั่วโมง! ฉันรู้ว่ามีบางอย่างเช่นนี้ แต่ฉันไม่สามารถจำมันได้ ฉันซุ่มซ่อนคำถามนี้อยู่ รอคุณอยู่ :) ... columnแน่นอน ชัดเจนมากแค่ไหน (ในการเข้าใจถึงปัญหาหลังเหตุการณ์) +1 ... ขอบคุณ ...
Peter.O

4
ฉันเพิ่งสังเกตเห็นว่าcolumn -s $'\t' -tละเว้นเซลล์ว่างเปล่าทำให้เซลล์ที่ตามมาทั้งหมดอยู่ทางขวาของมัน (บนบรรทัดนั้น) ย้ายไปทางซ้าย กล่าวคือเป็นผลมาจากบรรทัดว่างในไฟล์หรือมันจะเป็นสั้น ... :(
Peter.O

1
@masi แก้ไขแล้ว
glenn jackman

-n ไม่ทำงานใน RHEL มีทางเลือกอื่นหรือไม่?
Koshur

ในที่สุดฉันสามารถแสดงความคิดเห็นได้ดังนั้นต้องการทราบว่าก่อนหน้านี้ฉันได้เพิ่มคำตอบด้านล่างที่กล่าวถึงปัญหาของ Peter.O เกี่ยวกับการทำงานของเซลล์ว่างโดยใช้ nulls
เทคโน

11

คุณกำลังมองหาprคำสั่งสำรวย:

paste file1 file2 | pr -t -e24

แท็บ "-e24" คือ "ขยายแท็บหยุดเป็น 24 ช่องว่าง" โชคดีที่pasteใส่อักขระแท็บระหว่างคอลัมน์เพื่อให้prสามารถขยายได้ ฉันเลือก 24 โดยการนับตัวอักษรใน "นับซ้ำนับซ้ำ" และเพิ่ม 2


ขอบคุณ! "แท็บขยายหยุดเป็น 24 ช่องว่าง" หมายความว่าอะไร
ทิม

ฉันยังอัปเดตด้วยตัวอย่างที่วิธีการของคุณเกือบจะจับมันยกเว้นการเยื้องแนวเล็กน้อย
ทิม

"แท็บสต็อป" ตามปกติจะตีทุก 8 ช่องว่าง "123TABabc" จะได้รับการพิมพ์ด้วยตัวอักษร 'a' ความกว้าง 8 อักขระจากจุดเริ่มต้นของบรรทัด การตั้งค่าเป็น 24 จะทำให้ 'a' ที่ 24 char width ตั้งแต่เริ่มต้นบรรทัด
Bruce Ediger

คุณบอกว่า"-e24" คือ "แท็บขยายหยุดที่ 24 ช่องว่าง"ดังนั้นทำไมไม่ใช้expandคำสั่งโดยตรง: paste file1 file2 | expand -t 24?
WhiteWinterWolf

1
@Masi - คำตอบของฉันคล้ายกัน แต่มีความซับซ้อนน้อยกว่าที่คำตอบของ @ techno ด้านล่าง ไม่เรียกใช้sedจึงมีกระบวนการหนึ่งที่ไม่ทำงาน มันใช้prซึ่งเป็นคำสั่งที่เก่าแก่ย้อนไป Unix SysV expandวันผมคิดว่าดังนั้นจึงอาจมีอยู่ในการติดตั้งมากกว่า มันเป็นแค่โรงเรียนเก่าในระยะสั้น
Bruce Ediger

9

อัปเดต : นี่เป็นสคริปต์ที่ง่ายกว่ามาก (สำหรับสคริปต์สุดท้าย) เพียงแค่ผ่านชื่อไฟล์ตามที่คุณต้องการpaste... มันใช้htmlในการทำเฟรมดังนั้นมันจึงปรับแต่งได้ มันจะรักษาหลายช่องว่างและการจัดตำแหน่งคอลัมน์จะถูกเก็บไว้เมื่อพบตัวอักษรยูนิโค้ด อย่างไรก็ตามวิธีที่ผู้แก้ไขหรือผู้ดูเรนเดอร์แสดงยูนิโค้ดเป็นอีกเรื่องหนึ่งโดยสิ้นเชิง ...

┌──────────────────────┬────────────────┬──────────┬────────────────────────────┐
│ Languages            │ Minimal        │ Chomsky  │ Unrestricted               │
├──────────────────────┼────────────────┼──────────┼────────────────────────────┤
│ Recursive            │ Turing machine │ Finite   │     space indented         │
├──────────────────────┼────────────────┼──────────┼────────────────────────────┤
│ Regular              │ Grammars       │          │ ➀ unicode may render oddly │
├──────────────────────┼────────────────┼──────────┼────────────────────────────┤
│ 1 2  3   4    spaces │                │ Symbol-& │ but the column count is ok │
├──────────────────────┼────────────────┼──────────┼────────────────────────────┤
│                      │                │          │ Context                    │
└──────────────────────┴────────────────┴──────────┴────────────────────────────┘

#!/bin/bash
{ echo -e "<html>\n<table border=1 cellpadding=0 cellspacing=0>"
  paste "$@" |sed -re 's#(.*)#\x09\1\x09#' -e 's#\x09# </pre></td>\n<td><pre> #g' -e 's#^ </pre></td>#<tr>#' -e 's#\n<td><pre> $#\n</tr>#'
  echo -e "</table>\n</html>"
} |w3m -dump -T 'text/html'

---

บทสรุปของเครื่องมือที่นำเสนอในคำตอบ (จนถึงตอนนี้)
ฉันได้ดูพวกเขาอย่างใกล้ชิด นี่คือสิ่งที่ฉันได้พบ:

paste# เครื่องมือนี้เป็นเรื่องธรรมดาสำหรับทุกคำตอบที่นำเสนอ # มันสามารถจัดการไฟล์ได้หลายไฟล์ ดังนั้นจึงมีหลายคอลัมน์ ... ดีมาก! # มันคั่นแต่ละคอลัมน์ด้วยแท็บ ... ดี # เอาต์พุตไม่ได้ถูกทำเป็นตาราง

เครื่องมือทั้งหมดด้านล่างทั้งหมดลบตัวคั่นนี้! ... ไม่ดีถ้าคุณต้องการตัวคั่น

column # มันลบตัวคั่นของแท็บดังนั้นตัวระบุฟิลด์จะบริสุทธิ์โดยคอลัมน์ที่ดูเหมือนว่าจะจัดการค่อนข้างดี .. ฉันไม่ได้เห็นอะไรผิดพลาด ... # นอกเหนือจากการไม่มีตัวคั่นที่ไม่ซ้ำกันมันทำงานได้ดี!

expand # มีการตั้งค่าแท็บเดียวเท่านั้นจึงไม่สามารถคาดเดาได้เกินกว่า 2 คอลัมน์ # การจัดเรียงคอลัมน์ไม่ถูกต้องเมื่อจัดการยูนิโค้ดและลบตัวคั่นของแท็บดังนั้นตัวระบุฟิลด์จะบริสุทธิ์โดยการจัดเรียงคอลัมน์

pr# มีการตั้งค่าแท็บเดียวเท่านั้นจึงไม่สามารถคาดเดาได้เกิน 2 คอลัมน์ # การจัดตำแหน่งคอลัมน์ไม่ถูกต้องเมื่อจัดการยูนิโค้ดและจะลบตัวคั่นแท็บดังนั้นการระบุฟิลด์จะเป็นการจำแนกคอลัมน์อย่างหมดจด

สำหรับฉันcolumnมันเป็นโซลูตรอนที่ดีที่สุดอย่างเห็นได้ชัดในฐานะหนึ่งซับ .. คุณต้องการทั้งตัวคั่นหรือแท็บ tabluation ASCII - art ของไฟล์ของคุณอ่านใน .. มิฉะนั้น .. columnsค่อนข้างดี:)


นี่คือสคริปต์ที่ใช้งานไฟล์ใด ๆ และสร้างงานนำเสนอแบบแท็บ ASCII-art .. (จำไว้ว่ายูนิโค้ดอาจไม่แสดงผลตามความกว้างที่คาดไว้เช่น. ௵ซึ่งเป็นอักขระตัวเดียวซึ่งค่อนข้างแตกต่างจากคอลัมน์ ตัวเลขผิดเช่นในกรณีของยูทิลิตี้ที่กล่าวถึงข้างต้น) ... เอาต์พุตของสคริปต์ที่แสดงด้านล่างมาจากไฟล์อินพุต 4 ไฟล์ชื่อ F1 F2 F3 F4 ...

+------------------------+-------------------+-------------------+--------------+
| Languages              | Minimal automaton | Chomsky hierarchy | Grammars     |
| Recursively enumerable | Turing machine    | Type-0            | Unrestricted |
| Regular                | Finite            | —                 |              |
| Alphabet               |                   | Symbol            |              |
|                        |                   |                   | Context      |
+------------------------+-------------------+-------------------+--------------+

#!/bin/bash

# Note: The next line is for testing purposes only!
set F1 F2 F3 F4 # Simulate commandline filename args $1 $2 etc...

p=' '                                # The pad character
# Get line and column stats
cc=${#@}; lmax=                      # Count of columns (== input files)
for c in $(seq 1 $cc) ;do            # Filenames from the commandline 
  F[$c]="${!c}"        
  wc=($(wc -l -L <${F[$c]}))         # File length and width of longest line 
  l[$c]=${wc[0]}                     # File length  (per file)
  L[$c]=${wc[1]}                     # Longest line (per file) 
  ((lmax<${l[$c]})) && lmax=${l[$c]} # Length of longest file
done
# Determine line-count deficits  of shorter files
for c in $(seq 1 $cc) ;do  
  ((${l[$c]}<lmax)) && D[$c]=$((lmax-${l[$c]})) || D[$c]=0 
done
# Build '\n' strings to cater for short-file deficits
for c in $(seq 1 $cc) ;do
  for n in $(seq 1 ${D[$c]}) ;do
    N[$c]=${N[$c]}$'\n'
  done
done
# Build the command to suit the number of input files
source=$(mktemp)
>"$source" echo 'paste \'
for c in $(seq 1 $cc) ;do
    ((${L[$c]}==0)) && e="x" || e=":a -e \"s/^.{0,$((${L[$c]}-1))}$/&$p/;ta\""
    >>"$source" echo '<(sed -re '"$e"' <(cat "${F['$c']}"; echo -n "${N['$c']}")) \'
done
# include the ASCII-art Table framework
>>"$source" echo ' | sed  -e "s/.*/| & |/" -e "s/\t/ | /g" \'   # Add vertical frame lines
>>"$source" echo ' | sed -re "1 {h;s/[^|]/-/g;s/\|/+/g;p;g}" \' # Add top and botom frame lines 
>>"$source" echo '        -e "$ {p;s/[^|]/-/g;s/\|/+/g}"'
>>"$source" echo  
# Run the code
source "$source"
rm     "$source"
exit

นี่คือคำตอบเดิมของฉัน (ตัดแต่งเล็กน้อยแทนสคริปต์ด้านบน)

ใช้wcเพื่อรับความกว้างคอลัมน์และsedไปทางขวาด้วยอักขระที่มองเห็นได้. (สำหรับตัวอย่างนี้) ... จากนั้นpasteเข้าร่วมสองคอลัมน์ด้วยแท็บ char ...

paste <(sed -re :a -e 's/^.{1,'"$(($(wc -L <F1)-1))"'}$/&./;ta' F1) F2

# output (No trailing whitespace)
Languages.............  Minimal automaton
Recursively enumerable  Turing machine
Regular...............  Finite

หากคุณต้องการแยกคอลัมน์ขวาออก:

paste <( sed -re :a -e 's/^.{1,'"$(($(wc -L <F1)-1))"'}$/&./;ta' F1 ) \
      <( sed -re :a -e 's/^.{1,'"$(($(wc -L <F2)-1))"'}$/&./;ta' F2 )  

# output (With trailing whitespace)
Languages.............  Minimal automaton
Recursively enumerable  Turing machine...
Regular...............  Finite...........

ขอบคุณ! คุณทำงานได้ค่อนข้างมาก ที่น่าตื่นตาตื่นใจ.
ทิม

5

คุณเกือบจะแล้ว pasteใส่อักขระแท็บระหว่างแต่ละคอลัมน์ดังนั้นสิ่งที่คุณต้องทำคือขยายแท็บ (ฉันถือว่าไฟล์ของคุณไม่มีแท็บ) คุณจำเป็นต้องกำหนดความกว้างของคอลัมน์ด้านซ้าย ด้วยยูทิลิตี้ GNU (ล่าสุด) wc -Lแสดงความยาวของบรรทัดที่ยาวที่สุด สำหรับระบบอื่นให้ทำการส่งรหัสผ่านครั้งแรกด้วย awk +1คือปริมาณของพื้นที่ว่างที่คุณต้องการระหว่างคอลัมน์

paste left.txt right.txt | expand -t $(($(wc -L <left.txt) + 1))
paste left.txt right.txt | expand -t $(awk 'n<length {n=length} END {print n+1}')

หากคุณมียูทิลิตี้คอลัมน์ BSD คุณสามารถใช้มันเพื่อกำหนดความกว้างของคอลัมน์และขยายแท็บได้ในครั้งเดียว ( เป็นอักขระแท็บตัวอักษรภายใต้ bash / ksh / zsh คุณสามารถใช้$'\t'แทนและในเชลล์ใด ๆ ที่คุณสามารถ"$(printf '\t')"ใช้ได้)

paste left.txt right.txt | column -s '␉' -t

ในรุ่นของฉันwcคำสั่งจะต้องเป็น: wc -L <left.txt... เพราะเมื่อชื่อไฟล์ถูก spedified เป็นบรรทัดคำสั่งหาเรื่องชื่อของมันจะถูกส่งออกไปยัง stdout
Peter.O

4

นี่คือหลายขั้นตอนดังนั้นจึงไม่เหมาะ แต่จะไป

1) file1.txtพบความยาวของสายที่ยาวที่สุดใน

while read line
do
echo ${#line}
done < file1.txt | sort -n | tail -1

ด้วยตัวอย่างของคุณบรรทัดที่ยาวที่สุดคือ 22

2) ใช้ awk เพื่อ pad file1.txt, padding แต่ละบรรทัดน้อยกว่า 22 ตัวอักษรถึง 22 กับprintfคำสั่ง

awk 'FS="---" {printf "%-22s\n", $1}' < file1.txt > file1-pad.txt

หมายเหตุ: สำหรับ FS file1.txtใช้สตริงที่ไม่ได้อยู่ใน

3) ใช้วางตามที่คุณเคยทำมาก่อน

$ paste file1-pad.txt file2.txt
Languages               Minimal automaton
Recursively enumerable  Turing machine
Regular                 Finite

หากนี่คือสิ่งที่คุณทำบ่อยๆสิ่งนี้สามารถเปลี่ยนเป็นสคริปต์ได้อย่างง่ายดาย


ในรหัสของคุณเพื่อค้นหาบรรทัดที่ยาวที่สุดคุณต้องการwhile IFS= read -r lineไม่เช่นนั้นเชลล์จะกัดเซาะช่องว่างและแบ็กสแลช แต่เชลล์ไม่ใช่เครื่องมือที่ดีที่สุดสำหรับงานนั้น รุ่นล่าสุดของ coreutils GNU ได้wc -L(ดูคำตอบของเฟร็ด) หรือคุณสามารถใช้ awk 'n<length {n=length} END {print +n}'awk:
Gilles 'หยุดความชั่วร้าย'

4

ฉันไม่สามารถแสดงความคิดเห็นกับคำตอบของ glenn jackman ได้ดังนั้นฉันจึงเพิ่มสิ่งนี้เพื่อแก้ไขปัญหาของเซลล์ว่างที่ Peter.O ตั้งข้อสังเกต การเพิ่มตัวอักขระเป็นโมฆะก่อนแต่ละแท็บจะลดการทำงานของตัวคั่นที่ถือว่าเป็นการหยุดพักครั้งเดียวและแก้ไขปัญหา (เดิมทีฉันใช้ช่องว่าง แต่การใช้ null char จะช่วยลดช่องว่างพิเศษระหว่างคอลัมน์)

paste file1 file2 | sed 's/\t/\0\t/g' | column -s $'\t' -t

หากตัวอักขระ null เป็นสาเหตุของปัญหาด้วยเหตุผลหลายประการให้ลอง:

paste file1 file2 | sed 's/\t/ \t/g' | column -s $'\t' -t

หรือ

paste file1 file2 | sed $'s/\t/ \t/g' | column -s $'\t' -t

ทั้งสองsedและมีความcolumnแตกต่างกันในการนำไปใช้กับรสชาติและเวอร์ชันของ Unix / Linux โดยเฉพาะ BSD (และ Mac OS X) เทียบกับ GNU / Linux


คำสั่ง sed นั้นดูเหมือนจะไม่ทำอะไรเลย ฉันแทนที่คำสั่งคอลัมน์ด้วยod -cและฉันไม่เห็นไบต์ว่างใด ๆ นี่คือเซนโตสและอูบุนตู
glenn jackman

1
สิ่งนี้ใช้ได้กับฉันใน RedHat EL4 ทั้ง sed และคอลัมน์ดูเหมือนจะแตกต่างกันตามกาลเวลาและระบบ ใน Ubuntu 14.4 การใช้งาน\0ไม่ได้ผลnullแต่\x0ก็ทำได้ อย่างไรก็ตามคอลัมน์นั้นมีline too longข้อผิดพลาด สิ่งที่ง่ายที่สุดดูเหมือนจะใช้พื้นที่และอยู่กับตัวละครพิเศษ
เทคโน

0

อาคารในคำตอบของ bahamat : นี้สามารถทำได้ทั้งหมดในawkการอ่านไฟล์เพียงครั้งเดียวและไม่ได้สร้างไฟล์ชั่วคราวใด ๆ เพื่อแก้ปัญหาดังกล่าวให้ทำ

awk '
        NR==FNR { if (length > max_length) max_length = length
                  max_FNR = FNR
                  save[FNR] = $0
                  next
                }
                { printf "%-*s", max_length+2, save[FNR]
                  print
                }
        END     { if (FNR < max_FNR) {
                        for (i=FNR+1; i <= max_FNR; i++) print save[i]
                  }
                }
    '   file1 file2

เช่นเดียวกับawkสคริปต์จำนวนมากของ ilk นี้การอ่านครั้งแรกข้างต้นfile1บันทึกข้อมูลทั้งหมดในsaveอาร์เรย์และคำนวณความยาวบรรทัดสูงสุดพร้อมกัน จากนั้นจะอ่านfile2 และพิมพ์ข้อมูลที่บันทึกไว้ ( file1) แบบคู่ขนานกับข้อมูลปัจจุบัน ( file2) สุดท้ายหากfile1ยาวกว่าfile2(มีอีกหลายบรรทัด) เราจะพิมพ์สองสามบรรทัดสุดท้ายของfile1 (บรรทัดที่ไม่มีบรรทัดที่สอดคล้องกันในคอลัมน์ที่สอง)

เกี่ยวกับprintfรูปแบบ:

  • "%-nns"พิมพ์สตริงที่จัดชิดซ้ายในฟิลด์nnอักขระที่กว้าง
  • "%-*s", nnทำสิ่งเดียวกัน - *บอกให้เอาความกว้างของฟิลด์จากพารามิเตอร์ถัดไป
  • โดยการใช้สำหรับการที่เราได้รับทั้งสองช่องว่างระหว่างคอลัมน์ เห็นได้ชัดว่าสามารถปรับได้maxlength+2nn+2

สคริปต์ด้านบนใช้ได้กับไฟล์สองไฟล์เท่านั้น มันสามารถแก้ไขได้เล็กน้อยเพื่อจัดการกับสามไฟล์หรือเพื่อจัดการกับสี่ไฟล์เป็นต้น แต่นี่อาจเป็นเรื่องที่น่าเบื่อและเป็นแบบฝึกหัด แต่ก็เปิดออกไม่ได้ยากที่จะปรับเปลี่ยนให้จัดการกับ หมายเลขใด ๆของไฟล์:

awk '
        FNR==1  { file_num++ }
                { if (length > max_length[file_num]) max_length[file_num] = length
                  max_FNR[file_num] = FNR
                  save[file_num,FNR] = $0
                }
        END     { for (j=1; j<=file_num; j++) {
                        if (max_FNR[j] > global_max_FNR) global_max_FNR = max_FNR[j]
                  }
                  for (i=1; i<=global_max_FNR; i++) {
                        for (j=1; j<file_num; j++) printf "%-*s", max_length[j]+2, save[j,i]
                        print save[file_num,i]
                  }
                }
    '   file*

นี่คล้ายกับสคริปต์แรกของฉันยกเว้น

  • มันกลายmax_lengthเป็นอาร์เรย์
  • มันกลายmax_FNRเป็นอาร์เรย์
  • มันเปลี่ยนsaveเป็นอาเรย์สองมิติ
  • มันอ่านทุกไฟล์ที่ประหยัดทุกเนื้อหา จากนั้นจะเขียนเอาต์พุตทั้งหมดจากENDบล็อก

ฉันรู้ว่าคำถามนี้เก่า ฉันเพิ่งสะดุดเมื่อมัน ฉันเห็นด้วยนั่นpasteคือทางออกที่ดีที่สุด; paste file1 file2 | column -s $'\t' -tโดยเฉพาะอย่างเกล็นแจ๊กแมน แต่ฉันคิดว่ามันคงจะสนุกถ้าได้ลองปรับปรุงawkวิธีนี้
G-Man
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.