我需要从文本文件中获取表格格式的输出,并且要通过以下awk命令来实现。
定界文件
ACTIVE#1238917238971238#USA#The U.S. is a country of 50 states covering a vast swath of North America.
ACTIVE#21389721839781237812#INDIA#India, officially the Republic of India, is a country in South Asia.
ACTIVE#3121278372183782137812#AUSTRALIA#Australia, officially the Commonwealth of Australia, is a sovereign country comprising the mainland of the Australian continent
AWK命令
awk -F"#" 'BEGIN {{printf "%-80s\n","--------------------------------------------------------------------------------------------------------------------------------------"} {printf "|%-12s|%-30s|%-38s|%-50s|\n","STATUS","ID", "Country", "Description"} {printf "%-80s\n","--------------------------------------------------------------------------------------------------------------------------------------"}} {printf "|%-12s|%-30s|%-38s|%-50s|\n",$1,$2,$3,$4} END{printf "%-80s\n","--------------------------------------------------------------------------------------------------------------------------------------"}' /tmp/test.txt
如果您可以看到Description列的输出,则它不会在其自己的列中格式化输出,而是由于字符串长度而使整个表弄乱了。
有人可以查看并建议我如何更好地显示“描述”列的输出吗?
答案 0 :(得分:4)
我会使用Term::Table模块(可通过操作系统的程序包管理器安装或通过CPAN进行安装)在perl中完成此操作,该模块将自动计算出列宽并根据需要包装文本:
import pygame as pg
import cv2
import random
pg.init()
display_width = 1000
display_height = 1000
BLUE = 47, 158, 189
RED = 255, 0, 0
display = pg.display.set_mode((display_width, display_height))
pg.display.set_caption("Cars Evolution")
icon = pg.image.load("icon.png")
pg.display.set_icon(icon)
clock = pg.time.Clock()
car_url = "car_img.png"
car_direction = 0 # car_direction from -1 to 1
beam_url = "beam_img.png"
beam_x = 200
beam_y = 200
beam_width = 20
beam_height = 160
total_level_width = 5000
total_level_height = 5000
class Beam(pg.sprite.Sprite):
def __init__(self, input_beam_url, input_beam_x, input_beam_y):
pg.sprite.Sprite.__init__(self)
self.x = input_beam_x
self.y = input_beam_y
self.image = pg.image.load(input_beam_url)
self.width = 20
self.height = 160
self.rect = self.image.get_rect()
def draw_beam(self):
self.x -= car.delta_x
self.y -= car.delta_y
display.blit(self.image, (self.x, self.y))
pg.draw.rect(display, RED, pg.Rect(self.x, self.y, self.width, self.height), 2)
class Car(pg.sprite.Sprite):
def __init__(self, input_car_url):
pg.sprite.Sprite.__init__(self)
self.image = pg.image.load(input_car_url)
self.x = display_width / 2
self.y = display_height / 3
self.width = 46
self.height = 89
self.rect = self.image.get_rect()
self.delta_x = 0
self.delta_y = 0
def draw_car(self):
display.blit(self.image, (self.x, self.y))
pg.draw.rect(display, RED, pg.Rect(self.x, self.y, self.width, self.height), 2)
def move_car(self, vertical_ind, horizontal_ind, speed):
self.delta_x = horizontal_ind * speed
self.delta_y = vertical_ind * speed
def is_collision(self, input_beams_list):
collide_beam_list = pg.sprite.spritecollide(self, input_beams_list, False)
if collide_beam_list:
print("collided")
return True
def close_game():
game = False
pg.quit()
quit()
beams_amount = 5
beams_list = pg.sprite.Group()
random.seed(57)
for beam in range(beams_amount):
beam_to_add = Beam(beam_url, random.randint(beam_width, display_width - beam_width), random.randint(beam_height, display_height - beam_height))
beams_list.add(beam_to_add)
car = Car(car_url)
def run_game():
game = True
while game:
for event in pg.event.get():
if event.type == pg.QUIT:
close_game()
display.fill(BLUE)
# Drawing
beams_list.update()
car.draw_car()
car.move_car(0.5, 0, 5)
for sprite_object in beams_list.sprites():
sprite_object.draw_beam()
car.is_collision(beams_list)
#close_game()
pg.display.update()
clock.tick(60)
run_game()
用法示例:
function findSchedules(name, jsonNode)
{
if (hasChildren(jsonNode) == false)
{
data = csvToJSON(jsonNode['?value']);
dataPath = data['dataPath'];
schedulePoint = data['schedulePoint'];
if (schedulePoint != "" && schedulePoint != null && schedulePoint != "NO SCHEDULE")
return [[name, dataPath, csvToJSON(jsonNode['?value'])['schedulePoint']]];
else
return [];
}
schedules = [];
for (node in jsonNode)
{
if (isValidNode(node) == true)
schedules = schedules.concat(findSchedules(node, jsonNode[node]));
/*
If instead I wrote:
if (isValidNode(node) == true)
{
prevSchedules = findSchedules(node, jsonNode[node]);
schedules = schedules.concat(prevSchedules);
}
which is what I had originally, the recursion would not work correctly. Why are these two
statements different?
*/
}
data = csvToJSON(jsonNode['?value']);
dataPath = data['dataPath'];
schedulePoint = data['schedulePoint'];
if (schedulePoint != "" && schedulePoint != null && schedulePoint != "NO SCHEDULE")
schedules.push([name, dataPath, schedulePoint]);
return schedules;
}
请考虑一下,由于perl formats,它也可以在没有任何非核心模块的情况下完成。我实际上更喜欢这种方式,因为它可以更好地自动换行(尽管更改表或单个列的整体宽度变得更加麻烦):
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
use Term::Table;
my @lines = map { chomp; [ split /#/ ] } <>;
say for Term::Table->new(
max_width => 80,
header => ["Status", "ID", "Country", "Description"],
rows => \@lines
)->render;
$ ./table.pl < input.txt
+--------+--------------------------+-----------+--------------------------+
| Status | ID | Country | Description |
+--------+--------------------------+-----------+--------------------------+
| ACTIVE | 1238917238971238 | USA | The U.S. is a country of |
| | | | 50 states covering a va |
| | | | st swath of North Americ |
| | | | a. |
| | | | |
| ACTIVE | 21389721839781237812 | INDIA | India, officially the Re |
| | | | public of India, is a co |
| | | | untry in South Asia. |
| | | | |
| ACTIVE | 3121278372183782137812 | AUSTRALIA | Australia, officially th |
| | | | e Commonwealth of Austra |
| | | | lia, is a sovereign coun |
| | | | try comprising the mainl |
| | | | and of the Australian co |
| | | | ntinent |
+--------+--------------------------+-----------+--------------------------+
答案 1 :(得分:4)
我让UNIX实用程序fold
对要包装的字段进行换行,因为它知道尝试在空格处分割等,以使包装的文本尽可能地可读:
$ cat tst.awk
BEGIN {
FS = "#"
OFS = "|"
}
NR == 1 {
split("8 12 10 45",fldWidths," ")
rowWidth = NF + 1 # for the OFSs between fields and at the start/end of the line
for (i in fldWidths) {
rowWidth += fldWidths[i]
}
rowSep = sprintf("%*s",rowWidth,"")
gsub(/ /,"-",rowSep)
print rowSep
split("STATUS ID Country Description",hdrs," ")
for (i=1; i<=NF; i++) {
printf "%s%-*s", OFS, fldWidths[i], hdrs[i]
}
print OFS
print rowSep
}
{
numRows = 0
for (fldNr=1; fldNr<=NF; fldNr++) {
cmd = "printf \047%s\n\047 \047" $fldNr "\047 | fold -s -w " fldWidths[fldNr]
rowNr = 0
while ( (cmd | getline line) > 0 ) {
rows[++rowNr,fldNr] = line
numRows = (numRows > rowNr ? numRows : rowNr)
}
close(cmd)
}
for (rowNr=1; rowNr<=numRows; rowNr++) {
for (fldNr=1; fldNr<=NF; fldNr++) {
printf "%s%-*s", OFS, fldWidths[fldNr], rows[rowNr,fldNr]
}
print OFS
}
print rowSep
}
。
$ awk -f tst.awk file
--------------------------------------------------------------------------------
|STATUS |ID |Country |Description |
--------------------------------------------------------------------------------
|ACTIVE |123891723897|USA |The U.S. is a country of 50 states covering |
| |1238 | |a vast swath of North America. |
--------------------------------------------------------------------------------
|ACTIVE |213897218397|INDIA |India, officially the Republic of India, is |
| |81237812 | |a country in South Asia. |
--------------------------------------------------------------------------------
|ACTIVE |312127837218|AUSTRALIA |Australia, officially the Commonwealth of |
| |3782137812 | |Australia, is a sovereign country comprising |
| | | |the mainland of the Australian continent |
--------------------------------------------------------------------------------
按摩适合的字段宽度。
答案 2 :(得分:2)
编辑: 使用标题尝试以下操作。
error
由于OP尚未提及在字段中添加空格的逻辑,但是从输出中看可以说它可能基于字段中的最大长度值,因此,基于此假设,您可以尝试以下方法(根据显示的示例。
subscribe(success, error)
以上解决方案的说明: 添加了以上详细说明。
app.ts
答案 3 :(得分:1)
这是另一个awk。它计算场的平均长度,然后计算要用于输出的终端的比例。可能有比平均值(或最大值)更好的方法,但我只尝试了2种方法。它使用tput cols
来获得端子宽度:
$ awk '
BEGIN {
FS="#" # delims
OFS="" # to allow length==0
}
NR==FNR { # avg field lenghts *
for(i=1;i<=NF;i++)
avg[i]+=length($i)
next
}
FNR==1 {
if(("tput cols"|getline cols)<0 || cols<2*NF-1) { # get terminal width
print "Yours is too small" # exit if too small
exit # in reality fails when
} # field width rounds to 0
for(i in avg) {
avg[i]=avg[i]/(NR-1) # * avg divided here
avgs+=avg[i]
}
for(i=1;i<=NF;i++) # below: field terminal
size[i]=((v=sprintf("%0.f",((avg[i]/avgs)*cols)-1))>0?v:1) # proportions
} # rounded with %0.f, min 1
{
while(length>0) # while unprinted chars
for(i=1;i<=NF;i++) { # keep outputing
printf "%-" size[i] "s%s",substr($i,1,size[i]),(i==NF?ORS:"|")
$i=substr($i,size[i]+1) # cut printed from fields
}
}' file file # 2 runs
64宽终端的输出:
AC|123891723|US|The U.S. is a country of 50 states covering a v
TI|8971238 |A |ast swath of North America.
VE| | |
AC|213897218|IN|India, officially the Republic of India, is a c
TI|397812378|DI|ountry in South Asia.
VE|12 |A |
AC|312127837|AU|Australia, officially the Commonwealth of Austr
TI|218378213|ST|alia, is a sovereign country comprising the mai
VE|7812 |RA|nland of the Australian continent
| |LI|
| |A |