awk - 为一系列行更改特定列中的字符串而不会丢失空格/格式
问题描述
我有一个包含很多行的文件,但我希望将X
我的第五列中前 4635 行的字符串更改为另一个字符串A
,而不会丢失列之间的原始制表符/间距。
我希望改变(对于一定范围的线路)
ATOM 2732 HN SER X 176 181.410 174.270 311.410 0.00 0.00
ATOM 2733 CA SER X 176 180.170 172.920 310.330 0.00 0.00
ATOM 2734 HA SER X 176 179.860 171.950 310.720 0.00 0.00
ATOM 2735 CB SER X 176 179.010 173.910 310.790 0.00 0.00
ATOM 2736 HB1 SER X 176 178.020 173.710 310.340 0.00 0.00
ATOM 2737 HB2 SER X 176 178.910 173.930 311.900 0.00 0.00
进入
ATOM 2732 HN SER A 176 181.410 174.270 311.410 0.00 0.00
ATOM 2733 CA SER A 176 180.170 172.920 310.330 0.00 0.00
ATOM 2734 HA SER A 176 179.860 171.950 310.720 0.00 0.00
ATOM 2735 CB SER A 176 179.010 173.910 310.790 0.00 0.00
ATOM 2736 HB1 SER A 176 178.020 173.710 310.340 0.00 0.00
ATOM 2737 HB2 SER A 176 178.910 173.930 311.900 0.00 0.00
我想出了以下代码,
awk '{if (NR>=1&&NR<=4635) split($0, a, FS, seps); a[5]="A"; for (i=1;i<=NF;i++) printf("%s%s", a[i], seps[i]); print ""}' dat > tmp
但似乎文件中的所有行现在都A
在第五列,而不是第 1-4635 行。我们欢迎所有的建议!
解决方案
如果您的输入是示例中所示的固定宽度字段,那么您可以使用FIELDWIDTHS
with GNU awk
:
awk -v FIELDWIDTHS='21 1 *' -v OFS= 'NR<=4635{$2="A"} 1'
这里,第一个字段由21
字符组成,第二个字段是1
字符,其余字段是第三个字段。然后,您可以仅为所需行更改第二个字段。
如果输入不是固定宽度,则可以使用sed
or perl
:
# GNU sed
sed -E '1,4635 s/^((\S+\s+){4})\S+/\1A/'
# if \s and \S isn't supported
sed -E '1,4635 s/^(([^[:space:]]+[[:space:]]+){4})[^[:space:]]+/\1A/'
perl -pe 's/^(\S+\s+){4}\K\S+/A/ if $.<=4635'
推荐阅读
- spring - 当异常不可重试时向 DLQ 发送消息
- c# - ExchangeService FindItems 突然间断不工作
- html - 如何去除底部的空白
- azure - 将 DropWizard 部署到 Azure
- jenkins - 在用户级别设置环境变量
- python - 将表格插入邮件正文
- android - 模拟器硬件键盘错误映射
- python - 当我输入 source env/bin/activate 时如何在 vs 代码编辑器中激活 virtualenv 它没有激活
- python - 如何根据列表中的项目从 xlsx 文件中返回一行
- docker - 如何修复 Kubernetes 创建容器错误