如果我有文件:
1 0 1
1 1 0
0 0 1
我如何用以下栏目中的数字(如果有的话)填写空格,以便获得:
1 1 0 1
1 1 0 0
0 0 1 1
我试过了:
awk '{
for (i=1;i<=NF;i+=2) {
if ((($i)==" ") && ($(i+1)!=" ")) {
($i)==($(i+1))
}
print
}
}'
但我没有得到所需的输出。我想为每个其他列执行此操作,因此for循环中的+=2
。
或者,如果awk
有办法忽略空格,我的问题可以解决吗?有办法吗?
谢谢。
答案 0 :(得分:4)
使用FIELDWIDTHS的GNU awk:
$ cat tst.awk
BEGIN { FIELDWIDTHS="1 1 1 1 1 1 1"; OFS="" }
{
for (i=(NF-2);i>0;i-=2) {
$i = ($i==" " ? $(i+2) : $i)
}
print
}
$ awk -f tst.awk file
1 1 0 1
1 1 0 0
0 0 1 1
请注意,这会向后传播值,因此即使多个连续值丢失,也会填充它们。如果最后一个值丢失,您没有说要做什么,所以这假设不会发生或者您没事如果结果是空白的结果。
答案 1 :(得分:2)
替代sed
$ sed -r 's/ ([0-9])/\1 \1/'
答案 2 :(得分:1)
本着Unix的精神,这是<head>
<title>story : cat</title>
</head>
<a class="results" href="www.hello.com" title="">title</a>
和 import json
fp =open('/path/tp/my/file')
mystr = fp.read()
fp.close()
data = json.loads(mystr)
的易于理解的组合:
sed
awk
为输入中缺少的字段填写sed 's/^ /@/; s/ / @/g' file |
awk '{
for (i=1;i<=NF;i+=2) {
if ($i=="@") $i = $(i+1)
}
print
}'
:
sed 's/^ /@/; s/ / @/g'
用@
替换空的第一个字段(感谢将正则表达式锚定到s/^ /@/
行的开头)@
用^
替换任何其他空字段(由于使用s/ / @/g'
,可能多个)。@
及其默认算法,即通过空白运行将输入拆分为字段。g
,在这种情况下 - 并且,如果匹配,则替换为相应的下一个字段的值。 答案 3 :(得分:1)
以下 sed 脚本处理具有多个数字/字符的数字和非数字数据。它通过使用 test 重复替换来处理多列空白的情况,直到替换不再成功:
sed ':a; s/ \([^ ]\+\)/\1 \1/g; ta'
使用 awk 一个类似的解决方案(可能效率较低,因为它与替换中不使用 g 标志后缀的情况相似)更加冗长 - 更不用说&#34;棘手&#34;为了正确:
awk '{ while(match($0, / [^ ]+/)) { $0 = substr($0, 1, RSTART-1) substr($0, RSTART+2, RLENGTH-2) substr($0, RSTART+1, length($0)-RLENGTH+2) } print }'
两种实现都保留尾随空白并打印空白行。
答案 4 :(得分:0)
gawk的
awk -F ' ' 'NF>1&&$2~/^[0-9]|^ [0-9]/{a=+$2;if(length($1)<2){sub("$",a,$1)}else{sub(" "," "a)}}1' file
1 1 0 1
1 1 0 0
0 0 1 1
答案 5 :(得分:-1)
谢谢大家的好评!我还编写了一个更笨重的解决方案,但我必须在sed
之前使用awk
:
我首先将FS
更改为\t
以获取:
1 0 1
1 1 0
0 0 1
sed 's/ /x/g' file |
awk 'BEGIN {FS=OFS="\t"} {
for (i=1;i<=NF;i+=2) {
if ($i=="x") {
$i=($(i+1))
}
}
}1'
这给出了:
1 1 0 1
1 1 0 0
0 0 1 1