我有一个数据文件(cou.data)
USSR 8649 275 Asia
Cananda 3852 25 North America
China 3705 1032 Asia
USA 3615 237 North America
Brazil 3286 134 South America
India 1267 746 Asia
Mexico 762 78 North America
France 211 55 Europe
Japan 144 120 Asia
Germany 96 61 Europe
England 94 56 Europe
Taiwan 55 144 Asia
North Korea 44 2134 Asia
此数据中只有空格,没有制表符。
我想用“:”替换所有空格,但国名的空格保持不变。
也就是说,我所需的输出应如下所示:
USSR:8649:275:Asia
Cananda:3852:25:North America
China:3705:1032:Asia
USA:3615:237:North America
Brazil:3286:134:South America
India:1267:746:Asia
Mexico:762:78:North America
France:211:55:Europe
Japan:144:120:Asia
Germany:96:61:Europe
England:94:56:Europe
Taiwan:55:144:Asia
North Korea:44:2134:Asia
我已经动了脑筋,只能写这个
awk '{ gsub(/([a-zA-Z] +[0-9]|[0-9] +[a-zA-Z]|[0-9] +[0-9])/, ":"); print }' cou.data
但是输出不正确。
USS:64:7:sia
Canand:85::orth America
Chin:70:03:sia
US:61:3:orth America
Brazi:28:3:outh America
Indi:26:4:sia
Mexic:6::orth America
Franc:1::urope
Japa:4:2:sia
German:::urope
Englan:::urope
Taiwa::4:sia
North Kore::13:sia
一些不应该删除的零件不见了。
如何修改我的AWK代码,或者有一种简单的解决方案来获得我想要的?
ps
awk '{ print gensub(/([a-zA-Z])( )([a-zA-Z])/, "\\1~\\3", "g", $0) }' cou.data | sed -r 's/ +/:/g; s/~/ /g'
答案 0 :(得分:3)
您需要捕获组和反向引用,并非所有awk
实现都支持。GNU awk
使用gensub
支持它。我建议使用{{1} }代替
sed
$ sed -E 's/ +([0-9])/:\1/g; s/([0-9]) +/\1:/g' ip.txt
USSR:8649:275:Asia
Cananda:3852:25:North America
China:3705:1032:Asia
USA:3615:237:North America
Brazil:3286:134:South America
India:1267:746:Asia
Mexico:762:78:North America
France:211:55:Europe
Japan:144:120:Asia
Germany:96:61:Europe
England:94:56:Europe
Taiwan:55:144:Asia
North Korea:44:2134:Asia
启用ERE,某些sed版本需要-E
而不是-r
-E
匹配一个或多个空格,后跟一个数字。我们只需要替换空格,但保持数字不变。因此,捕获数字并使用反向引用在替换部分中引用它s/ +([0-9])/:\1/g
将涵盖数字后跟空格的情况s/([0-9]) +/\1:/g
内来定义的-从左到右,()
指的是此类组,\1
指的是第二组,依此类推
使用\2
,您可以避免使用捕获组
perl
perl -pe 's/ +(?=\d)|\d\K +/:/g' ip.txt
仅在空格后跟数字或数字前匹配空格
使用 +(?=\d)|\d\K +
,请参见gawk String-Manipulation Functions了解语法和详细信息
GNU awk
答案 1 :(得分:2)
您可以使用反向引用来包含要与gnu awk一起保留的原始文档的部分。使用gensub并将反向引用添加到正则表达式中将为您提供以下内容。
gawk '{ print gensub(/(([a-zA-Z]) +([0-9]))|(([0-9]) +([a-zA-Z]))|(([0-9]) +([0-9]))/, "\\2\\5\\8:\\3\\6\\9", "g"); }' file
请参阅https://www.gnu.org/software/gawk/manual/gawk.html#index-substitute-in-string