我的文件中有一个字符串:
7017556626 TEST BSAB 20191108 TEST123 3333 1111 BSAB 11
7007760674 TESTCHAS 20191108 TEST123 4444 5555 CHAS 22
7017556626 TEST 20191108 TEST123 3333 1111 CHAS 33
7017556626 TEST SSEQ 20191108 TEST123 2222 7777 BSAB 44
7007760674 TESTCHAS 20191108 TEST123 1111 0000 55
我需要在位置 16 之前添加空格
7017556626 TEST BSAB 20191108 TEST123 3333 1111 BSAB 11
7007760674 TEST CHAS 20191108 TEST123 4444 5555 CHAS 22
7017556626 TEST 20191108 TEST123 3333 1111 CHAS 33
7017556626 TEST SSEQ 20191108 TEST123 2222 7777 BSAB 44
7007760674 TEST CHAS 20191108 TEST123 1111 0000 55
我该怎么做?
答案1
在GNU sed
扩展模式下:
sed -Ee 's/^(.{15})([^ ])/\1 \2/' file
用GNU sed
另一种方法:
sed -e '
h ; # hold a copy in case we need it
s/./\n&/16; # place a marker before the 16-char in the current line
/\n /g ; # in case the marker sees a space to its right, revert the changes
s/\n/ / ; # in case not then remove the marker
' file
和Perl
:
perl -lpe '$_ = "@{[unpack q[A15A*]]}" if index($_," ",15) != 15' file
结果:
7017556626 TEST BSAB 20191108 TEST123 3333 1111 BSAB 11
7007760674 TEST CHAS 20191108 TEST123 4444 5555 CHAS 22
7017556626 TEST 20191108 TEST123 3333 1111 CHAS 33
7017556626 TEST SSEQ 20191108 TEST123 2222 7777 BSAB 44
7007760674 TEST CHAS 20191108 TEST123 1111 0000 55
答案2
如同sed,您可以使用可编写脚本的编辑器ed
:
printf '%s\n' '1,$s/^\(.\{15\}\)\([^ ]\)/\1 \2/' 'wq' | ed -s file
这会以“静默”模式向 ed 发送两个换行符分隔的命令:
1,$s/^\(.\{15\}\)\([^ ]\)/\1 \2/
-- 在每一行(1,$
从第 1 行到最后一行的范围),执行搜索和替换。从行首 (^
) 搜索任意 15 个字符,后跟一个非空格字符;如果找到,则将前 15 个字符分组为子表达式 #1,将非空格字符分组为子表达式 #2。将该文本替换为子表达式 #1、一个空格,然后替换为子表达式 #2——本质上,如果下一个字符不是空格,则在第 15 个字符后面放置一个空格。wq
-- 将文件写回磁盘并退出ed
答案3
和awk
:
awk 'substr($0,16,1) != " " { $0=substr($0,0,15)" "substr($0,16) }1' file
如果第16位的字符串不是空格字符,则将当前行更改为前缀、空格字符和后缀。然后打印当前行 ( 1
)。