Asg*_*ard 1 csv awk if-statement case nawk
我有一个大的.csv文件要处理,我的元素是随机排列的,如下所示:
XXXXXX,XX, ,MLOCAL,MREMOTE,33222,,56
XXXXXX,XX, ,,,,,
XXXXXX,XX, ,,
XXXXXX,XX, ,,
XXXXXX,XX, ,,,,,
XXXXXX,XX, ,,,,,
XXXXXX, XX, ,,22/10/201218/10/2012MREMOTEMLOCAL332225622/10/201218/10/2012MLOCAL34199322/10/2012MREMOTE935682808/10/2012LOCALREMOTE193161525322/10/201222/10/2012REMOTELOCAL186587138366622/10/201222/10/2012REMOTE118030613419/10/2012
其中字段LOCAL,REMOTE,MLOCAL或MREMOTE显示等:
MLOCAL,第4个字段是MREMOTE,则第5个和第7个字段表示值和日期MLOCAL,第6个和第8 个字段表示值和日期MREMOTE LOCAL或仅REMOTE)时,第4个和第5个字段表示字段3的值和日期.现在,我使用以下方法拆分这些行:
nawk 'BEGIN{
while (getline < "'"$filedata"'")
split($0,ft,",");
name=ft[1];
ID=ft[2]
?=ft[3]
?=ft[4]
....................
Run Code Online (Sandbox Code Playgroud)
但是因为我找不到第3和第4字段的模式,所以我很难继续为每个数组元素分配var名称,以便将它们用于进一步处理.
现在,我尝试使用"case"语句,但不适用于awk或nawk(仅在gawk中按预期工作).我也试过这个:
if ( ft[3] == "MLOCAL" && ft[4]!= "MREMOTE" )
{
MLOCAL=ft[3];
MLOCAL_qty=ft[4];
MLOCAL_TIMESTAMP=ft[5];
}
else if ( ft[3] == MLOCAL && ft[4] == MREMOTE )
{
MLOCAL=ft[3];
MREMOTE=ft[4];
MOCAL_qty=ft[5];
MREMOTE_qty=ft[6];
MOCAL_TIMESTAMP=ft[7];
MREMOTE_TIMESTAMP=ft[8];
}
else if ( ft[3] == MREMOTE && ft[4] != MOCAL )
{
MREMOTE=ft[3];
MREMOTE_qty=ft[4];
MREMOTE_TIMESTAMP=ft[5];
..........................................
Run Code Online (Sandbox Code Playgroud)
但它不能正常工作.
所以,如果你有任何想法如何处理这个问题,我将很感激地给我一个提示,以便能够找到一个模式,以涵盖从上面的所有可能的情况.
编辑
我不知道如何感谢你的帮助.现在,我要做的比上面写的更复杂,我会尽量简单地描述,否则我会让你们很困惑.我的输出应该如下:
NAME,UNIQUE_ID,VOLUME_ALOCATED,MLOCAL_VALUE,MLOCAL_TIMESTMP,MLOCAL_limit,LOCAL_VALUE,LOCAL_TIMESTAMP,LOCAL_limit,MREMOTE_VALUE,MREMOTE_TIMESTAMP,REMOTE_VALUE,REMOTE_TIMESTAMP
(其中,MLOCAL_limit和LOCAL_limit是之间减法结果VOLUME_ALOCATED和MLOCAL_VALUE或LOCAL_VALUE)
因此,在我的输出文件中,字段位置应排列如下:
第4场 = MLOCAL_VALUE,第5场 = MLOCAL_TIMESTMP,第7场 = LOCAL_VALUE,
第8场 = LOCAL_TIMESTAMP,第10场 = MREMOTE_VALUE,第11场 = MREMOTE_TIMESTAMP,第12场 = REMOTE_VALUE,第13场 =REMOTE_TIMESTAMP
现在,一个例子是这样的:以下输入:name,ID,VOLUME_ALLOCATED,MLOCAL,MREMOTE,33222,56,22/10/2012,18/10/2012
name,ID,VOLUME_ALLOCATED,REMOTE,234455,19/12/2012
我应该处理这一行,输出应该是这样的:
name,ID,VOLUME_ALLOCATED,33222,22/10/2012,MLOCAL_LIMIT, ,,,56,18/10/2012,,
7th,8th,9th,12th,和13th字段为空,因为没有相关的信息,以:LOCAL_VALUE,LOCAL_TIMESTAMP,LOCAL_limit,REMOTE_VALUE,和REMOTE_TIMESTAMP
要么
name,ID,VOLUME_ALLOCATED,,,,,,,,,234455,9/12/2012
4th,5th,6th,7th,8th,9th,10th和11th,田应为空值,因为有大约没有资料:MLOCAL_VALUE,MLOCAL_TIMESTAMP,MLOCAL_LIMIT,LOCAL_VALUE,LOCAL_TIMESTAMP,LOCAL_LIMIT,MREMOTE_VALUE,MREMOTE_TIMESTAMP
VOLUME_ALLOCATED从其他csv文件(称为"info.csv")中检索,该文件基于ID先前在脚本中处理的字段,如:
info.csv
VOLUME_ALLOCATED,ID,CLIENT
5242881,64,subscriber
567743,24,visitor
data.csv
NAME,64,MLOCAL,341993,23/10/2012
NAME,24,LOCAL$ REMOTE,2347$ 4324,19/12/2012$18/12/2012
现在,我的代码是这样的:
#! /usr/bin/bash
input="info.csv"
filedata="data.csv"
outfile="out"
nawk 'BEGIN{
while (getline < "'"$input"'")
{
split($0,ft,",");
volume=ft[1];
id=ft[2];
client=ft[3];
key=id;
volumeArr[key]=volume;
clientArr[key]=client;
}
close("'"$input"'");
while (getline < "'"$filedata"'")
{
gsub(/\$/,","); # substitute the $ separator with comma
split($0,ft,",");
volume=volumeArr[id]; # Get the volume from the volumeArr, using "id" as key
segment=clientArr[id]; # Get the client mode from the clientArr, using "id" as key
NAME=ft[1];
id=ft[2];
Run Code Online (Sandbox Code Playgroud)
在这里我卡住了,因为我不知道如何处理第3和第4个字段,所以找不到正确的方法来设置其余的字段.
? =ft[3];
? =ft[4];
Run Code Online (Sandbox Code Playgroud)
对不起,如果我让你很困惑,但这是我现在的情况.谢谢
您没有提供样本输入的预期输出,但这里是一个开始,展示如何获取2种不同格式的输入行的值:
$ cat tst.awk
BEGIN{ FS=","; OFS="\t" }
{
delete value # or use split("",value) if your awk cant delete arrays
if ($4 ~ /LOCAL|REMOTE/) {
value[$3] = $5
date[$3] = $7
value[$4] = $6
date[$4] = $8
}
else {
value[$3] = $4
date[$3] = $5
}
print
for (type in value) {
printf "%15s%15s%15s\n", type, value[type], date[type]
}
}
$ awk -f tst.awk file
xxxxxx,xx,MLOCAL,MREMOTE,33222,56,22/10/2012,18/10/2012
MREMOTE 56 18/10/2012
MLOCAL 33222 22/10/2012
xxxxxx,xx,MREMOTE,MLOCAL,33222,56,22/10/2012,18/10/2012
MREMOTE 33222 22/10/2012
MLOCAL 56 18/10/2012
xxxxxx,xx,MLOCAL,*341993,22/10/2012*
MLOCAL *341993 22/10/2012*
xxxxxx,xx,MREMOTE,9356828,08/10/2012
MREMOTE 9356828 08/10/2012
xxxxxx,xx,LOCAL,REMOTE,19316,15253,22/10/2012,22/10/2012
REMOTE 15253 22/10/2012
LOCAL 19316 22/10/2012
xxxxxx,xx,REMOTE,LOCAL,1865871,383666,22/10/2012,22/10/2012
REMOTE 1865871 22/10/2012
LOCAL 383666 22/10/2012
xxxxxx,xx,REMOTE,1180306134,19/10/2012
REMOTE 1180306134 19/10/2012
Run Code Online (Sandbox Code Playgroud)
如果您发布预期的输出,我们可以帮助您更多.