拆分文件内容并存储到数组中或通过分隔符迭代throgh文件内容

时间:2017-07-13 10:39:39

标签: linux bash awk ifs

我有下面的文件说是MemberFile.txt。其中包含由分隔符'#'分隔的记录,分隔符'#'以换行符开头,是该行的单个字符。因此有三条记录。

 self.dismiss(animated: true, completion: nil)

我们如何在没有3RECORDSFILE # [FIRSTNAME ] FirstName01 [MIDDLENAME ] MiddleName01 [LASTNAME ] LastName01 [ADDRESS Q] AddressOf #001 Pune [ADDRESS S] AddressOf #001 # [FIRSTNAME ] NameFirst02 [MIDDLENAME ] MiddleName02 [LASTNAME ] LastName02 [ADDRESS Q] AddressOf [002 [ADDRESS N] Addres Mumbai sOf [002 # [FIRSTNAME ] 03FirstName [MIDDLENAME ] MiddleName03 [LASTNAME ] LastName03 [ADDRESS Q] Address Of 003] 整个文件的情况下使用IFS迭代记录。我在下面试了一下但没有用。看起来它是逐行读取而不是指定的IFS。不知道哪里出错了。

cat

我尝试使用awk的其他选项。指定分隔符并存储到数组中。这也没有产生预期的结果。

#!/bin/bash
while IFS='^#$' read r
do
echo $r
#do something more
done < MemberFile.txt

请你看看并纠正错误的地方。我很喜欢这个bash脚本。我需要在每条记录上再次执行一些操作。

3 个答案:

答案 0 :(得分:0)

使用此gnu awk将输入细分为#\n分隔的记录:

awk -v RS='#\n' 'NR>1{print "==================", NR, "================"; print}' file
================== 2 ================
[FIRSTNAME      ]   FirstName01
[MIDDLENAME     ]   MiddleName01
[LASTNAME       ]   LastName01
[ADDRESS       Q]   AddressOf #001 Pune
[ADDRESS       S]   AddressOf #001

================== 3 ================
[FIRSTNAME      ]   NameFirst02
[MIDDLENAME     ]   MiddleName02
[LASTNAME       ]   LastName02
[ADDRESS       Q]   AddressOf [002
[ADDRESS       N]   Addres Mumbai sOf [002

================== 4 ================
[FIRSTNAME      ]   03FirstName
[MIDDLENAME     ]   MiddleName03
[LASTNAME       ]   LastName03
[ADDRESS       Q]   Address Of 003]

您可以对每条记录执行操作,例如使用此awk命令打印所有FIRSTNAME

awk -v RS='#\n' 'NR>1{print $3}' file

FirstName01
NameFirst02
03FirstName

答案 1 :(得分:0)

如果您确实需要使用数组,则可以执行以下操作:

#!/bin/bash
arry=""
cnt=0
while read -r line
do
        if [[ "$line" == "#" ]]
        then
                cnt=$(($cnt+1))
        else
                arry[$cnt]=${arry[$cnt]}$line"\n"
        fi
done < Member.txt
for ((i=1;i<=$cnt;i++))
do
        echo -e ${arry[$i]}
        # do some other stuff here
done

我们首先在循环中取每行Member.txt并在&#34;#&#34;时增加一个计数器。遇到并使用此计数器创建每个元素保存每个数据块。然后我们遍历数组并打印出每个块,执行其他任何操作。

答案 2 :(得分:0)

anubhava的答案似乎很有用,但如果您需要输入bash变量,那么实际上并不存在。完整的过程是将记录读入脚本语言(如anubhava所做),然后用空分隔符打印出记录,然后将记录读入bash变量。使用空分隔符,因为您知道文本不包含空值。关键是让read命令使用空字符作为其分隔符。

我在第一部分使用了perl而不是awk:

cat Member.txt | perl -e 'use warnings; use strict; my $stdin_raw; { local $/; $stdin_raw = <STDIN>; }; my @records = split(/\n#/m, $stdin_raw);

print(join(“\ 0”,@ record),“\ 0”);' |而IFS =读-r -d $'\ 0'记录;回声“得到记录:$记录”;完成

但是,由于您所做的只是将“#”替换为null,因此可以使用sed进行此简单替换:

cat Member.txt | sed 's/^#$/\x00/' | while IFS= read -r -d $'\0' record; do echo "Got record: $record"; done

请注意,IFS=需要阻止read一次只消费一个字。 -d $'\0'将分隔符设置为空字符。 -r用于原始模式:它告诉read忽略数据中的特殊字符。

但我同意anubhava关于一件事:脚本语言比bash用于文本处理更强大和有用。我建议使用perl而不是awk,因为awk的规则不像普通的编程语言。尽管在awk中写了大约一百个脚本,但我从来没有掌握它。我发现调试awk脚本很难,即使我面前有文档。当你尝试做复杂的事情时,awk是一种简单的语言。 Perl有一个更陡峭的初始学习曲线,但它很快就会停止感觉像黑魔法。