如何解决我想逐行读取文件并仅存储一些值
>QDN;6135785008
-------------------------------------------------------------------------------
DN:;;;;;5785008;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TYPE:;SINGLE;PARTY;LINE
SNPA:;613;;;SIG:;DT;;;;LNATTIDX:;N/A;;;;;;;;;;;;;
LINE;EQUIPMENT;NUMBER:;;;;;BSAC;;39;0;00;01;;;
LINE;CLASS;CODE:;;IBN;;;
IBN;TYPE:;STATION
CUSTGRP:;;;;;;;;BSA_POS;;;;;SUBGRP:;0;;NCOS:;1
CARDCODE:;;V5LOOP;;;;GND:;N;;PADGRP:;NPDGP;;BNV:;NL;MNO:;N
PM;NODE;NUMBER;;;;;:;;;;80
PM;TERMINAL;NUMBER;:;;;;2
OPTIONS:
CWT;DGT;DDN;NOAMA;
;
-------------------------------------------------------------------------------
>QDN;6160160260
-------------------------------------------------------------------------------
DN:;;;;;0160260;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TYPE:;SINGLE;PARTY;LINE
SNPA:;616;;;SIG:;DT;;;;LNATTIDX:;N/A;;;;;;;;;;;;;
LINE;EQUIPMENT;NUMBER:;;;;;BSAC;;39;0;00;03;;;
LINE;CLASS;CODE:;;IBN;;;
IBN;TYPE:;STATION
CUSTGRP:;;;;;;;;BSA_POS;;;;;SUBGRP:;0;;NCOS:;15
CARDCODE:;;V5LOOP;;;;GND:;N;;PADGRP:;NPDGP;;BNV:;NL;MNO:;N
PM;NODE;NUMBER;;;;;:;;;;80
PM;TERMINAL;NUMBER;:;;;;4
OPTIONS:
CWT;3WC;DGT;DDN;NOAMA;
;
----
我想读取所有行并将一些值存储到4个变量中。例如; var number(用“ QDN”表示的行的第二列),var类型(以PARTY开头的行),var snpa和var选项(在发生OPTIONS之后,它存储下一行的值)。输出可能是用分号分隔的文本文件(例如:var1; var2; var3; var4)。这部分起作用。我有以下代码,但无法将所有这些变量汇总在一起。我尝试在第一个循环中创建另一个while循环,以验证循环的“最后一次”检查(分隔信息块的分号),但是它也不起作用。
while IFS= read -r line || [[ -n "$line" ]]; read -r secondline; do
if [[ "$line" =~ ^'>QDN' ]]; then
number=$(echo "$line" | awk -F ';' 'NF {print $2;}')
elif [[ "$line" =~ ^'TYPE' ]]; then
type=$(echo "$line" | awk -F ';' 'NF {print $2" "$3" "$4;}')
elif [[ "$line" =~ ^'SNPA' ]]; then
snpa=$(echo "$line" | awk -F ';' 'NF {print $2;}')
elif [[ "$line" =~ ^'OPTIONS' ]]; then
options=$(echo "${secondline}")
fi
echo $number";"$type";"$snpa";"$options
done < "file.txt
;613;CWT;3WC;DGT;DDN;NOAMA;SACB;ACT;I976;$;$;N;
;613;CWT;3WC;DGT;DDN;NOAMA;SACB;ACT;I976;$;$;N;
;613;CWT;DGT;DDN;NOAMA;
;613;CWT;DGT;DDN;NOAMA;
;613;CWT;DGT;DDN;NOAMA;
;613;CWT;DGT;DDN;NOAMA;
;616;CWT;DGT;DDN;NOAMA;
;616;CWT;DGT;DDN;NOAMA;
;616;CWT;DGT;DDN;NOAMA;
;616;CWT;DGT;DDN;NOAMA;
;616;DGT;ARTY LINE
;616;DGT;ARTY LINE
;616;DGT;ARTY LINE
你们中的任何人都可以帮忙吗?
解决方法
重复的Awk类似小片段通常表明您应该改用Awk重写整个脚本。
以下内容假定OPTIONS总是排在其他字段之后。消除此限制并不难,但有了这一限制,代码非常简单。
awk -F ';' 'BEGIN { OFS=";" }
/^>QDN/ { number = $2 }
/^TYPE/ { type = $2 " " $3 " " $4 }
/^SNPA/ { snpa = $2 }
/^OPTIONS/ { options = 1; next }
options { print number,type,snpa,$0;
number = type = snpa = options = "" }' file.txt
您可能应该单独从文件中删除DOS回车,但是如果您还需要处理损坏的文件,则可以在顶部轻松添加NF { sub(/\r/,"") }
。
如果您在行读取循环中调用awk
,则很可能是您做错了。您应该考虑以纯awk
或纯bash
的方式进行。以下是普通的bash
版本:
#!/bin/bash
while read -r line; do
line=${line%$'\r'} # in case lines end in \r\n. Otherwise,you can remove this line
case $line in
\>QDN* | TYPE* ) printf %s "${line#*;};" ;;
SNPA* ) line=${line#*;}; printf %s "${line%%;*};" ;;
OPTIONS* ) read -r line && printf '%s\n' "$line" ;;
esac
done < file.txt
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。