我在文本文件中有一堆以下模式的字符串:
201194_2012110634 Appliance 130 AB i Some optional (Notes )
300723_2017050006(2016111550) Device 16 AB i Note
第一部分是序列号,第二部分是日期。设备/设备名称和型号(大约10个可能的不同名称)是日期编号之后和之前的字符串(包括AB i
)。
我能够使用隔离日期和序列
SERIAL=${line:0:6}
YEAR=${line:7:4}
在此之后,我试图隔离设备名称和注释:
#!/bin/bash
while IFS= read line || [[ -n $line ]]; do
NAME=${line#*[a-zA-Z]}
STRINGAP='Appliance '"${line/#*Appliance/}"
第一种方法是在第一个字母出现在行中之后拿走所有东西,这给了我
NAME = ppliance 130 AB i Some optional (Notes )
第二种方法是为大约10个可能的设备/设备名称编写测试,然后在减去的测试之后附加设备名称。然后测试与设备/设备(或其他名称)实际匹配的变量,然后使用该变量输入数据库。
是否可以在文本文件中编写一行内容来选择所有内容,包括一行中的第一个字母?然后我减去AB i
之后的所有内容以获取注释,而AB i
之前的所有内容都将成为设备名称。
答案 0 :(得分:1)
删除$ {line#* [az-A-Z]}行(如您所见,将删除名称的第一个字符),而改用
STRINGAP=$(echo "$line" | sed 's/^[0-9_]* \(.*\) AB i.*/\1/')
这会删除前导数字和下划线,以及从“ AB i”到末尾的所有内容。
编辑:详细信息不清楚-您是否要保留“ AB i”,并且它始终是“ AB i”吗?如果需要,将行更改为
STRINGAP=$(echo "$line" | sed 's/^[0-9_]* \(.* AB i\).*/\1/')
我也忘记了文本行周围的双引号。
答案 1 :(得分:1)
您可以使用sed
和read
来更好地控制解析。
tmp> line2="300723_2017050006(2016111550) Device 16 AB i Note"
tmp> read serial date type val <<<$(echo $line2 | \
sed 's/\([0-9]*\)_\([0-9]*\)[^A-Z]*\(Device\|Appliance\) \
\([0-9]*\).*/\1 \2 \3 \4/')
tmp> echo "$serial|$date|$type|$val"
300723|2017050006|Device|16
基本上,读取允许您在一行中分配多个变量。 sed语句解析该行,并为您提供以空格分隔的结果输出。如果您不介意额外运行sed,也可以分别读取每个变量:
device="$(echo $line2 | sed -e 's/^.*Device \([0-9]*\).*/\1/;t;d')"
appliance="$(echo $line2 | sed -e 's/^.*Appliance \([0-9]*\).*/\1/;t;d')"
这样,$device
会用设备填充(如果存在的话),否则为空白(请注意正则表达式末尾的-e
和;t;d
,以防止它转储该行)不匹配。)
答案 2 :(得分:1)
您的问题尚不清楚,但似乎您可能正在尝试将字符串解析为子字符串。使用GNU awk尝试此操作以使match()的第三个参数保持一致,并让我们知道您是否正在寻找其他东西:
$ awk 'match($0,/^([0-9]+)_([0-9]+)(\([0-9]+\))?\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)/,a) {
for (i=1; i<=8; i++) {
print i, a[i]
}
print "---"
}' file
1 201194
2 2012110634
3
4 Appliance
5 130
6 AB
7 i
8 Some optional (Notes )
---
1 300723
2 2017050006
3 (2016111550)
4 Device
5 16
6 AB
7 i
8 Note
---
例如,如果您想要CSV输出,则只需:
$ awk -v OFS=',' 'match($0,/^([0-9]+)_([0-9]+)(\([0-9]+\))?\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)/,a) {
for (i=1; i<=8; i++) {
printf "%s%s", a[i], (i<8?OFS:ORS)
}
}' file
201194,2012110634,,Appliance,130,AB,i,Some optional (Notes )
300723,2017050006,(2016111550),Device,16,AB,i,Note
适合的按摩...