Linux:修复文件中的输出内容

时间:2014-05-15 16:12:30

标签: linux bash

真的需要你的帮助。我有一个文件,其中包含一行中的(字段:值)等数据

File.A

A:13 B:2 D:5 F:92 G:3 ...

我创建了一个包含" A到Z"。

的文件

File.B

A B C D E F G H I J ...

尝试使用bash脚本获取内容并修复输出,该输出将插入带有0值的未命中行。

A:13 B:2 C:0 D:5 E:0 F:92 G:3 H:0 ...
想了两天......但是我的头脑里还没有发现。有什么办法可以解决吗?

3 个答案:

答案 0 :(得分:7)

让我们进行大括号扩展工作:{A..Z}扩展为所有字母列表:

$ echo {A..Z}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

然后我们可以遍历所有行grep。如果匹配,我们打印该行;否则,我们打印letter:0

for letter in {A..Z}
do
   grep "^$letter" file || echo "$letter:0"
done

测试

$ for letter in {A..Z}; do grep "^$letter" file || echo "$letter:0"; done
A:13
B:2
C:0
D:5
E:0
F:92
G:3
H:0
I:0
J:0
K:0
L:0
M:0
N:0
O:0
P:0
Q:0
R:0
S:0
T:0
U:0
V:0
W:0
X:0
Y:0
Z:0

现在您更新了问题并且输入文件包含同一行中的所有内容,您可以使用此grep来匹配:

grep -o "$word:[0-9]*" file

然后用空格替换新行:

$ for word in {A..Z}; do grep -o "$word:[0-9]*" file || echo "$word:0"; done | tr '\n' ' '
A:13 B:2 C:0 D:5 E:0 F:92 G:3 H:0 I:0 J:0 K:0 L:0 M:0 N:0 O:0 P:0 Q:0 R:0 S:0 T:0 U:0 V:0 W:0 X:0 Y:0 Z:0

答案 1 :(得分:2)

如果您喜欢awk,可以试试这个:

awk -F: -vRS=" " '
{ c[$1] = $2 }
END{ 
  for(i=65;i<91;++i){ 
    a=sprintf("%c", i)
    printf("%c:%d ",i,c[a])
  }
}' A

其中A是您的文件。第一个块构建一个已设置的所有值的数组。读取完所有文件后,循环将遍历A(65)​​到Z(90)的ascii值,并打印出已在数组中设置的值。缺少的那些打印为0

输出:

A:13 B:2 C:0 D:5 E:0 F:92 G:3 H:0 I:0 J:0 K:0 L:0 M:0 N:0 O:0 P:0 Q:0 R:0 S:0 T:0 U:0 V:0 W:0 X:0 Y:0 Z:0

由于每个人显然都无法从我的回答中得到足够的信息,所以这是另一种可以做到的方式,受到@fedorqui's answer中使用的{A..Z}范围的启发:

awk -F: -vRS=" " '
NR==FNR { a[i++] = $1; next }
{ b[$1] = $2 }
END{for(i=0;i<length(a);++i)printf("%c:%d ",a[i],b[a[i]])}' - <<<$(echo {A..Z}) A

第一个块读入字母表中的所有字母,从而减少了解字符代码的需要。第二个块从您的文件A构建一个数组。读取文件后,将打印出所有值,从而产生与上述相同的输出。

答案 2 :(得分:2)

Pure Bash,没有外部流程。如果在行中找到字母或字母后面的字母,则打印匹配,否则为0。

read content < "$infile"

for letter in {A..Z}; do
  if [[ $content =~ ${letter}:[[:digit:]]+ ]] ; then
    echo "${BASH_REMATCH[0]}"
  else
    echo "${letter}:0"
  fi
done

或更短

for x in {A..Z}; do
  [[ $content =~ ${x}:[0-9]+ ]] && echo "${BASH_REMATCH[0]}" || echo "${x}:0"
done