AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 460276
Accepted
Curious Sam
Curious Sam
Asked: 2018-08-04 01:35:06 +0800 CST2018-08-04 01:35:06 +0800 CST 2018-08-04 01:35:06 +0800 CST

如何从第 30 个制表符或第 88 个空格开始格式化文件的最后 3 列

  • 772

Ubuntu 16.04 GNU bash,版本 4.4.0

我想格式化这个包含 1,264,524 行的邮政编码归档的文本文件。

#!/bin/bash

wget http://download.geonames.org/export/zip/allCountries.zip
unzip allCountries.zip
mv -f allCountries.txt .allCountries.txt
rm -f allCountries.zip

这是未格式化的文件的一部分。

AD AD100 Canillo                    42.5833  1.6667   6
AD AD200 Encamp                     42.5333  1.6333   6
AD AD300 Ordino                     42.6  1.55  6
AD AD400 La Massana                    42.5667  1.4833   6
AD AD500 Andorra la Vella                    42.5  1.5   6
AD AD600 Sant Julià de Lòria                    42.4667  1.5   6
AD AD700 Escaldes-Engordany                     42.5  1.5667   6
AR 3636  POZO CERCADO (EL CHORRO (F), DPTO. RIVADAVIA (S))  Salta A              -23.4933 -61.9267 3
AR 4123  LAS SALADAS Salta A              -25.7833 -64.5 4
AR 4126  BARADERO Salta A              -26.0833 -65.263  3
AR 4126  EL CUIBAL   Salta A              -26.0833 -65.263  3
AR 4126  LA ASUNCION Salta A              -26.0833 -65.263  3
AR 4126  MIRAFLORES (TALA, DPTO. CANDELARIA) Salta A              -26.0833 -65.263  3
AR 4141  TOLOMBON Salta A              -26.2 -65.9167 4
AR 4141  QUISCA GRANDE  Salta A              -26.4367 -65.97   3
AR 4141  LA CIENEGUITA  Salta A              -26.4367 -65.97   3
AR 4141  MACHO RASTROJO Salta A              -26.4367 -65.97   3
AR 4190  ROSARIO DE LA FRONTERA  Salta A              -25.8 -64.9667 4
AR 4190  OVANDO   Salta A              -25.8 -65.1 4
AR 4190  SAN ESTEBAN Salta A              -25.8 -65.0333 3
AR 4190  LA BANDA (R. DE LA FRONTERA, DPTO. ROSARIO DE LA FRONTERA)  Salta A              -25.8 -65.0333 3
AR 4190  LA MATILDE  Salta A              -25.8 -65.0333 3
AR 4190  LAS PIEDRITAS  Salta A              -25.8 -65.0333 3
AR 4190  LOS POCITOS Salta A              -25.8 -65.0333 3
AR 4190  OJO DE AGUA (ROSARIO DE LA FRONTERA, DPTO. R.DE LA FRONTERA)   Salta A              -25.8 -65.0333 3
AR 4190  POTRERILLO (R. DE LA FRONTERA, DPTO. ROSARIO DE LA FRONTERA)   Salta A              -25.8 -65.0333 3

这应该是最终结果:

AD AD100 Canillo                                                                          42.5833     1.6667      6
AD AD200 Encamp                                                                           42.5333     1.6333      6
AD AD300 Ordino                                                                           42.6        1.56        6
AD AD400 La Massana                                                                       42.5667     1.4833      6
AD AD500 Andorra la Vella                                                                 42.5        1.6         6
AD AD600 Sant Julià de Lòria                                                              42.4667     1.5         6
AD AD700 Escaldes-Engordany                                                               42.5        1.5667      6
AR 3636  POZO CERCADO (EL CHORRO (F), DPTO. RIVADAVIA (S))  Salta A                       -23.4933    -61.9267    3
AR 4123  LAS SALADAS Salta A                                                              -25.7833    -64.5       4
AR 4126  BARADERO Salta A                                                                 -26.0833    -65.263     3
AR 4126  EL CUIBAL   Salta A                                                              -26.0833    -65.263     3
AR 4126  LA ASUNCION Salta A                                                              -26.0833    -65.263     3
AR 4126  MIRAFLORES (TALA, DPTO. CANDELARIA) Salta A                                      -26.0833    -65.263     3
AR 4141  TOLOMBON Salta A                                                                 -26.2       -65.9167    4
AR 4190  OJO DE AGUA (ROSARIO DE LA FRONTERA, DPTO. R.DE LA FRONTERA)   Salta A           -25.8       -65.0333    3
AR 4190  POTRERILLO (R. DE LA FRONTERA, DPTO. ROSARIO DE LA FRONTERA)   Salta A           -25.8       -65.0333    3

所以从左边第 3 列到最后一列的第 30 个制表符或 88 个空格应该开始。最后 3 列的第一个字符相隔 12 个空格。

每行都有数据,所以我尝试将最后 3 列剪切到另一个文件中。然后我尝试从原始文件中删除所有空格,然后将其格式化为列。第三列给我带来了麻烦,因为如果这样做

awk 'BEGIN{ OFS="\t"}{ print $1, $2, NR }' .allCountries.txt

AT      4873    Pehigen 34069
AT      4873    Hofberg 34070
AT      4873    Wiederhals      34071
AT      4873    Oberedt 34072
AT      4873    Oberegg 34073
AT      4873    Raitenberg      34074
AT      4873    Redltal 34075
AT      4873    Friedhalbing    34076
AT      4873    Unterhaselbach  34077
AT      4873    Redltal 34078
AT      4873    Erkaburgen      34079
AT      4873    Mayrhof 34080
AT      4873    Erdpries        34081
AT      4873    Grünbergsiedlung        34082
AT      4873    Brunnhölzl      34083
AT      4873    Seibrigen       34084
AT      4873    Kinast  34085
AT      4873    Stöckert        34086
AT      4873    Frankenburg     34087
AT      4873    Fischeredt      34088
AT      4873    Marigen 34089
AT      4873    Oberhaselbach   34090
AT      4873    Ottokönigen     34091
AT      4873    Fischigen       34092
AT      4873    Endriegl        34093

任何帮助都会很重要。

awk cut
  • 2 2 个回答
  • 150 Views

2 个回答

  • Voted
  1. Best Answer
    steve
    2018-08-04T07:13:49+08:002018-08-04T07:13:49+08:00

    这似乎做到了。作为一个简单的单行awk,它应该对 1.2m 行文件运行得相当快。通过根据您的示例创建一个 1.3m 行的虚拟文件,我看到它在具有 4GB 内存和 GNU Awk 4.0.2 的基本 CentOS 7 VM 上在 24 秒内完成。

    要从 StackExchange 获得一些准确的响应,您可能希望将示例输入连同示例输出一起发布到 pastebin。

    $ awk '{printf "%s %-6s%-81s%-12s%-12s%s\n",$1,$2,gensub(/[0-9.-]* +[0-9.-]* +[0-9]$/,"","g",substr($0,10)),$(NF-2),$(NF-1),$NF}' inp | head
    AD AD100 Canillo                                                                          42.5833     1.6667      6
    AD AD200 Encamp                                                                           42.5333     1.6333      6
    AD AD300 Ordino                                                                           42.6        1.55        6
    AD AD400 La Massana                                                                       42.5667     1.4833      6
    AD AD500 Andorra la Vella                                                                 42.5        1.5         6
    AD AD600 Sant Julià de Lòria                                                              42.4667     1.5         6
    AD AD700 Escaldes-Engordany                                                               42.5        1.5667      6
    AR 3636  POZO CERCADO (EL CHORRO (F), DPTO. RIVADAVIA (S))  Salta A                       -23.4933    -61.9267    3
    AR 4123  LAS SALADAS Salta A                                                              -25.7833    -64.5       4
    AR 4126  BARADERO Salta A                                                                 -26.0833    -65.263     3
    $
    

    在线尝试!

    • 1
  2. jesse_b
    2018-08-04T05:53:49+08:002018-08-04T05:53:49+08:00

    我能够使用以下脚本完成我认为您想要的事情,尽管我不确定它在 1 百万行以上的效果如何。

    #!/usr/local/bin/bash
    
    tmp_dir="$(mktemp -d -t 'text.XXXXX' || mktemp -d 2>/dev/null)"
    input=./input
    output=./output
    tmp_input1=${tmp_dir}/temp_input1.txt
    tmp_input2=${tmp_dir}/temp_input2.txt
    col1="${tmp_dir}/col1.txt"
    col2="${tmp_dir}/col2.txt"
    col3="${tmp_dir}/col3.txt"
    col4="${tmp_dir}/col4.txt"
    col5="${tmp_dir}/col5.txt"
    col6="${tmp_dir}/col6.txt"
    
    tr -s ' ' <"$input" > "$tmp_input1"
    
    awk '{print $1}' "$tmp_input1" > "$col1"
    
    awk '!($1="")' "$tmp_input1" > "$tmp_input2"
    
    awk '{print $1}' "$tmp_input2" > "$col2"
    
    awk '!($1="")' "$tmp_input2" > "$tmp_input1"
    
    awk '{print $NF}' "$tmp_input1" > "$col6"
    
    awk '!($NF="")' "$tmp_input1" > "$tmp_input2"
    
    awk '{print $NF}' "$tmp_input2" > "$col5"
    
    awk '!($NF="")' "$tmp_input2" > "$tmp_input1"
    
    awk '{print $NF}' "$tmp_input1" > "$col4"
    
    awk '!($NF="")' "$tmp_input1" > "$tmp_input2"
    
    cat "$tmp_input2" > "$col3"
    
    paste -d'\t' "$col1" "$col2" "$col3" "$col4" "$col5" "$col6"  | column -s$'\t' -t > "$output"
    
    rm -r "$tmp_dir"
    

    这会创建一堆 tmp 文件(每列一个,两个用于修改原始文件)并通过您的原始输入进行处理,一次删除一列,直到它与第 3 列一起留下。然后将所有 tmp 文件粘贴在一起制表符分隔并用于column根据需要格式化该输出。

    使用您给定的输入:

    $ ./script.sh
    $ cat output
    AD  AD100  Canillo                                                                42.5833   1.6667    6
    AD  AD200  Encamp                                                                 42.5333   1.6333    6
    AD  AD300  Ordino                                                                 42.6      1.55      6
    AD  AD400  La Massana                                                             42.5667   1.4833    6
    AD  AD500  Andorra la Vella                                                       42.5      1.5       6
    AD  AD600  Sant Julià de Lòria                                                    42.4667   1.5       6
    AD  AD700  Escaldes-Engordany                                                     42.5      1.5667    6
    AR  3636   POZO CERCADO (EL CHORRO (F), DPTO. RIVADAVIA (S)) Salta A              -23.4933  -61.9267  3
    AR  4123   LAS SALADAS Salta A                                                    -25.7833  -64.5     4
    AR  4126   BARADERO Salta A                                                       -26.0833  -65.263   3
    AR  4126   EL CUIBAL Salta A                                                      -26.0833  -65.263   3
    AR  4126   LA ASUNCION Salta A                                                    -26.0833  -65.263   3
    AR  4126   MIRAFLORES (TALA, DPTO. CANDELARIA) Salta A                            -26.0833  -65.263   3
    AR  4141   TOLOMBON Salta A                                                       -26.2     -65.9167  4
    AR  4141   QUISCA GRANDE Salta A                                                  -26.4367  -65.97    3
    AR  4141   LA CIENEGUITA Salta A                                                  -26.4367  -65.97    3
    AR  4141   MACHO RASTROJO Salta A                                                 -26.4367  -65.97    3
    AR  4190   ROSARIO DE LA FRONTERA Salta A                                         -25.8     -64.9667  4
    AR  4190   OVANDO Salta A                                                         -25.8     -65.1     4
    AR  4190   SAN ESTEBAN Salta A                                                    -25.8     -65.0333  3
    AR  4190   LA BANDA (R. DE LA FRONTERA, DPTO. ROSARIO DE LA FRONTERA) Salta A     -25.8     -65.0333  3
    AR  4190   LA MATILDE Salta A                                                     -25.8     -65.0333  3
    AR  4190   LAS PIEDRITAS Salta A                                                  -25.8     -65.0333  3
    AR  4190   LOS POCITOS Salta A                                                    -25.8     -65.0333  3
    AR  4190   OJO DE AGUA (ROSARIO DE LA FRONTERA, DPTO. R.DE LA FRONTERA) Salta A   -25.8     -65.0333  3
    AR  4190   POTRERILLO (R. DE LA FRONTERA, DPTO. ROSARIO DE LA FRONTERA) Salta A   -25.8     -65.0333  3
    
    • 0

相关问题

  • 根据第一个逗号之前的匹配删除重复行数

  • 在另一个文件之后逐行追加行

  • 如何删除两行之间的单行

  • 重新排列字母并比较两个单词

  • 多行文件洗牌

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve