使用shell脚本复制和替换文件中特定行的列

2024-04-20 08:30:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我有多个文件,其中的数据按如下方式排列(以空格分隔的列(此处以“-”表示):

数据
2500-OPQ--1000--UVA--XYZ
2501-LMN--1001--VNZ--OPQ
2502-OPQ---1002-USS--MNO
2503-LMN---1003-PQR--OGD
数据

在一个特定的行(这里例如2502)之后,我想移动第3列的内容,以便整个第3列完全对齐,文件的其余部分保持原样(第4列和第5列上的数据可能有不同的字符数):

数据
2500-OPQ--1000--UVA--XYZ
2501-LMN--1001--VNZ--OPQ
2502-OPQ--1002--USS--MNO
2503-LMN--1003--PQR--OGD
数据

我想使用bash或python脚本来实现这一点。

For more clarity, attached please find a figure showing the files I am working on. Left: Original file. Right: Modified file. After line 2997 (see column 2), column 5 is moved to the left, while the rest stays the same.


Tags: 文件the数据方式columnfilexyzuva
3条回答

请尝试:

awk '{printf "%4s%7d  %-3s %5s%4d %s\n", $1, $2, $3, $4, $5, substr($0, 28)}' input_file

其中input_file是从图片中提取的,看起来像:

ATOM   2996  H1  TIP3G 999     -14.190 -28.766  -0.221  0.00  0.00
ATOM   2997  H2  TIP3G 999     -14.390 -29.221  -1.040  0.00  0.00
ATOM   2998  OH2 TIP3G 1000     21.160  21.806  10.603  0.00  0.00
ATOM   2999  H1  TIP3G 1000     21.614  20.972  10.722  0.00  0.00

以及输出:

ATOM   2996  H1  TIP3G 999     -14.190 -28.766  -0.221  0.00  0.00
ATOM   2997  H2  TIP3G 999     -14.390 -29.221  -1.040  0.00  0.00
ATOM   2998  OH2 TIP3G1000      21.160  21.806  10.603  0.00  0.00
ATOM   2999  H1  TIP3G1000      21.614  20.972  10.722  0.00  0.00

通过修改printf中的格式字符串,可以调整列的间距和/或位置。你知道吗

如果要指定要处理的行,例如all lines after 2502,可以这样说:

awk 'NR<2502 {print; next} {printf "%4s%7d  %-3s %5s%4d %s\n", $1, $2, $3, $4, $5, substr($0, 28)}' input_file

它输出2502之前的行,然后将2502和之后的行重新格式化,尽管我不确定是否需要这样的切换。你知道吗

awk '{sub(/ -/," ")sub(/1002-|1003-/,"&-")}1' file

data
2500-OPQ 1000 UVA XYZ
2501-LMN 1001 VNZ OPQ
2502-OPQ 1002 USS MNO
2503-LMN 1003 PQR OGD
data   

这将满足您的需要:

$ awk -F'-*' '{ if ( $1 > 2501 && $1 ~ /[0-9]+/ ) { print $1"-"$2" "$3" "$4" "$5 } else if($1 ~ /[0-9]+/) { print $0}  }' input.txt

输出:

2500-OPQ 1000 UVA XYZ
2501-LMN 1001 VNZ OPQ
2502-OPQ 1002 USS MNO
2503-LMN 1003 PQR OGD

为了完整起见,这里有一个Python 3版本:

import re

input="""
data
2500-OPQ 1000 UVA XYZ
2501-LMN 1001 VNZ OPQ
2502-OPQ -1002-USS MNO
2503-LMN -1003-PQR OGD
data
"""

for line in input.splitlines() :
    if re.match('[0-9]+',line) :
        fields = re.split(r'-+', line)
        if int(fields[0]) > 2501 :
            print("{}-{} {} {} {}".format(fields[0],fields[1],fields[2],fields[3],fields[4]))
        else :
            print(line)

敬礼!你知道吗

相关问题 更多 >