![将带有嵌入头记录的文件分成两个文件](https://linux22.com/image/28400/%E5%B0%86%E5%B8%A6%E6%9C%89%E5%B5%8C%E5%85%A5%E5%A4%B4%E8%AE%B0%E5%BD%95%E7%9A%84%E6%96%87%E4%BB%B6%E5%88%86%E6%88%90%E4%B8%A4%E4%B8%AA%E6%96%87%E4%BB%B6.png)
我想使用 unix 脚本根据嵌入的标头记录将以下示例文本文件分成两个单独的文件:
CSI 447907 890947967201270
776666666 B
771555555 B
774444444 B
REL 447904 890947967201270
772222222 A
771111111 B+
770000000 A
CSI 447911 891096722201270
774444444 B+
778888888 A
779999999 A
REL 171077 889928722201270
774444444 B
773333333 B+
772222222 B+
771111111 C
PHY 114926 891987278201270
123456789 A
987654321 A
777777777 B+
结果文件:
文本文件1
CSI 447907 890947967201270
776666666 B
771555555 B
774444444 B
CSI 447911 891096722201270
774444444 B+
778888888 A
779999999 A
文本文件2
REL 447904 890947967201270
772222222 A
771111111 B+
770000000 A
REL 171077 889928722201270
774444444 B
773333333 B+
772222222 B+
771111111 C
PHY 114926 891987278201270
123456789 A
987654321 A
777777777 B+
标题记录的数量以及详细记录的数量都可以变化。列/字段是静态的。第一个文本文件包含 CSI 标头和相应的详细记录,而第二个文本文件是剩下的内容。
答案1
awk 的另一个典型工作:
POSIXLY_CORRECT=1 LC_ALL=C awk '
$1 ~ /^[A-Z]{3}$/ {
if ($1 == "CSI")
file = "csi.txt"
else
file = "rest.txt"
}
file {print > file}'
POSIXLY_CORRECT
仅当您的GNU awk在标准一致模式下awk
无法识别 except 时才如此。{...}
LC_ALL=C
确保[A-Z]
表示 ASCII 字符 fromA
到Z
,否则,该范围可能包含其他字符,具体取决于本地化设置。
如果在 Solaris 上,请使用command -p awk
或/usr/xpg4/bin/awk
,否则您可能最终/bin/awk
会不再使用它。
答案2
我使用了 while 循环并向下读取第一个 CSI 标头。然后我就可以编写标题和详细记录了。
这是我到目前为止所拥有的:
file="data.txt"
STR=CSI
while IFS= read -r line
do
if [[ ${line} = @(${STR}*) ]] then
echo $line > file2.txt
while IFS= read -r line2
do
echo $line2 >> file2.txt
done
fi
done <"$file"
史蒂文