给出以下形式的文本文件:
firstword<number1>,<string1>:<number2>,<string2>:<number3>,<string>:<number4>...
firstword<number1>,<string1>:<number2>,<string2>:<number3>,<string>:<number4>...
firstword<number1>,<string1>:<number2>,<string2>:<number3>,<string>:<number4>...
...
其中每一行可以彼此不同,并且可以具有任意数量的string:number对。 “第一字”始终是相同的。字符串和数字的内容可以更改,例如数字可以是“ 12345”,字符串可以是“ abc”(不带引号)。
此外,同一行可以有多次相同的字符串(多少行是未知的,每行不同),每条都有不同的关联编号。例如:
firstword123,abc:123,cde:234,abc:345,def:456
如果现在只想提取第一个单词和数字(在本例中为firstword123)以及特定字符串的一行中的所有string:number对,那么该怎么做?在上面的示例中,如果为字符串选择值“ abc”,则提取的行应类似于:
firstword123,abc:123,abc:345
我正在寻找一种适用于Bash(以及其他命令)的解决方案。
答案 0 :(得分:2)
您可以为此使用perl
#!/usr/bin/perl
my $first='firstword123';
my $str='abc';
while (<DATA>) {
next if not /^$first/;
print "$first";
print ",$_" for ($_ =~ /$str:\d+/g);
}
__DATA__
firstword123,abc:123,cde:234,abc:345,def:456
退出:
firstword123,abc:123,abc:345
答案 1 :(得分:1)
不是单线,而是全力以赴的解决方案。如果您需要更快的代码,我们可以用awk
或perl
...
$: cat keyscan
#! /bin/env bash
key="$1"
while read line
do start=${line//,*/}
line=${line#$start}
line=${line#,}
while [[ -n "$line" ]]
do case "$line" in
$key:[0-9]*) lead="${line//,*/}"
start="$start,$lead"
line="${line#$lead}"
line="${line#,}" ;;
*,*) line="${line#*,}" ;;
*) line='' ;;
esac
done
printf "$start\n"
done
$: cat data
firstword123,abc:123,cde:234,abc:345,def:456
$: ./keyscan abc < data
firstword123,abc:123,abc:345
$: ./keyscan def < data
firstword123,def:456
$: ./keyscan cde < data
firstword123,cde:234
它不会很快,因为它在输入的每一行上都有一个处理循环,但是可以在您提供的数据的示例行上工作。