我有一个文本文件,其中包含以下格式的行:
9999.0 @str:Attribute|ID=foo_1|SendingTime=2015-07-24 05:12:12.123|S-Id=9999|IDSource=Test_3|Qty=1555
从这里我想使用shell脚本从每一行中获取单个部分。比如说:
VAR1 = Attribute,
VAR2 = Date,
VAR3 = timeStamp,
VAR4 = Qty
主要问题是信息的顺序不同,有些信息的每行都有更多/更少的不需要的数据。因此拆分成阵列就不会削减它。
答案 0 :(得分:0)
解析复杂行的一般方法是使用正则表达式来描述它们,然后使用括号来表示哪些部分很有趣:
s='9999.0 @str:Attribute|ID=foo_1|SendingTime=2015-07-24 05:12:12.123|S-Id=9999|IDSource=Test_3|Qty=1555'
pattern='.*@str:\([^|]*\).*ID=\([^|]*\).*SendingTime=\([^|]*\).*Qty=\([^|]*\).*$'
extract_interesting() {
input=$1
pattern=$2
echo "$input" | sed s/"$pattern"/'\1#\2#\3#\4'/
}
函数extract_interesting()
将打印该行的四个有趣部分,以#
符号分隔:
extract_interesting "$s" "$pattern"
将打印
Attribute#foo_1#2015-07-24 05:12:12.123#1555
要将其读入单独的shell变量,请使用以下模式:
IFS=# read a b c d < <(extract_interesting "$s" "$pattern")
然后
echo "$a"; echo "$b"; echo "$c"; echo "$d"
将打印
Attribute
foo_1
2015-07-24 05:12:12.123
1555
答案 1 :(得分:0)
grep
带有Perl
正则表达式的示例:
#!/bin/bash
s="9999.0 @str:Attribute|ID=foo_1|SendingTime=2015-07-24 05:12:12.123|S-Id=9999|IDSource=Test_3|Qty=1555"
var1="$(echo "$s" |grep -oP "(?<=@str:)[^|]*")" # @str:
var2="$(echo "$s" |grep -oP "(?<=SendingTime=)[^|]*")" # SendingTime=
var3="${var2#* }" # Date
var2="${var2% *}" # timestamp
var4="$(echo "$s" |grep -oP "(?<=Qty=)[^|]*")" # Qty
echo "$var1 | $var2 | $var3 | $var4"
输出:
Attribute | 2015-07-24 | 05:12:12.123 | 1555
答案 2 :(得分:0)
这是一个简单的Awk脚本,它选取字段并按指定的顺序打印它们。
awk -F '\t' 'BEGIN { f = split("Attribute|Date|timeStamp|Qty", k, /\|/) }
{ n = split($2, a, /\|/); for (i=1; i<=n; ++i) {
if (a[i] ~ /^@str:/) v["Attribute"] = substr(a[i], 6);
else if (a[i] ~ /^SendingTime=/) {
v["Date"] = substr(a[i], 13, 10); v["timeStamp"] = substr(a[i], 24)
} else if (a[i] ~ /^Qty=/) v["Qty"] = substr(a[i], 5);
}
for (s=1; s<=f; s++) printf("%s=%s\n", k[s], v[k[s]]);
delete v }' inputfile
BEGIN
块按我们想要的顺序设置要收集和打印的字段标签的数组k
。最后的for
循环遍历此数组。主要的复杂性在中间块,我们进一步分割|
分隔符上的第二个字段并循环结果;我们要提取的每个字段都会根据匹配中的偏移量进行填充。
没有检查字段是否缺席,以及对输入(制表符分隔,是?)和输出格式的一些假设,因为您的问题不是很清楚。