我有一个名为input.txt
这样的输入文件:
powerOf|creating new file|failure
creatEd|new file creating|failure
powerAp|powerof server|failureof file
我提取文本,使其仅在第一场拳大写字母前,存放在output.txt
那些片段:
power
creat
我用sed
命令分离出的价值和它的正常工作。
从输出文件(output.txt
),我需要从第一场到grep
,并输出应该象下面这样:
Power
power:powerOf|creating new file|failure,powerAp|powerof server|failureof file
creat
creat:creatEd|new file creating|failure
我已经尝试了一些方法,但我没有得到预期的输出。
我尝试以下,但我发现重复的条目:
cat input.txt | cut -d '|' f1 >> input1.txt
cat input1.txt | s/\([a-z]\)\([A-Z]\)/\1 \2/g >> output.txt
while read -r line;do
echo $ line
cat input.txt |cut -d ‘|’ f1|grep $line >> output1. txt
done< "output.txt"
我在输入文件20000行。我不知道为什么我收到重复的输出。我究竟做错了什么?
击的解决方案:
#!/bin/bash
keys=()
declare -A map
while read line; do
key=$(echo ${line} | cut -d \| -f1 | sed -e 's/[[:upper:]].*$//')
if [[ -z "${map[$key]}" ]]; then
keys+=(${key})
map[$key]="${line}"
else
map[$key]+=",${line}"
fi
done
for key in ${keys[*]}; do
echo "${key}"
echo "${key}:${map[$key]}"
done
exit 0
也许一个Perl的解决方案是可以接受的OP太:
#!/usr/bin/perl
use strict;
use warnings;
my @keys;
my %map;
while (<>) {
chomp;
my($key) = /^([[:lower:]]+)/;
if (not exists $map{$key}) {
push(@keys, $key);
$map{$key} = [];
}
push(@{ $map{$key} }, $_);
}
foreach my $key (@keys) {
print "$key\n";
print "$key:", join(",", @{ $map{$key} }), "\n";
}
exit 0;
与给定的输入测试:
$ perl dummy.pl <dummy.txt
power
power:powerOf|creating new file|failure,powerAp|powerof server|failureof file
creat
creat:creatEd|new file creating|failure
OP后更新已重述原来的问题。解第一环路仅包括输入,而不是整个行的第二列中:
message=$(echo ${line} | cut -d \| -f2)
if [[ -z "${map[$key]}" ]]; then
keys+=(${key})
map[$key]="${message}"
else
map[$key]+=",${message}"
fi
与给定的输入测试:
$ perl dummy.pl <dummy.txt
power
power:creating new file,powerof server
creat
creat:new file creating
分解出useless uses of cat
和其他反模式,你基本上是在做
# XXX not a solution, just a refactoring of your code
sed 's/\([a-z]\)\([A-Z]\).*/\1/' input.txt | grep -f - input.txt
其提取线就好了,但没有采取任何措施加入他们的行列。如果要合并具有相同前缀的值的行,一个简单的awk脚本可能会做你的需要。
awk '{ key=$1; sub(/[A-Z].*/, "", key)
b[key] = (key in b ? b[key] "," : key ":" ) $0 }
END { for(k in b) print b[k] }' input.txt
我们提取前缀为key
。如果是,我们已经看到之前(在这种情况下,关联数组中存在b
的话)的关键,追加前值和一个逗号,否则初始化数组值的密钥本身,以及电流线前一个冒号。当我们完成后,通过循环累计键和打印的价值,我们存储每个。
若线长,2万行可能不适合到内存中一次,但如果你的榜样代表,应该是最温和的硬件一个不起眼的任务。