复制一个字符串形成一行并粘贴到另一行的末尾以获得基于模式的大文件
copy a string form a line and paste at the end in another line for a huge file based on pattern
我有以下要求。我正在尝试 运行 循环中的条件,这需要更多时间。是否有任何一次性命令不会花费更多时间来处理 70 MB 文件。
要求:
如果@pRECTYPE="SBSB" 行包含@pSBEL_MCTR_RSN="XXX" 标记,那么我们需要将其复制并附加到行末尾的下一个@pRECTYPE="SBEL 记录
文件 :note : 文件中不会有空行。我输入了 enter 以避免行继续
@pRUKE=dfgt@pRECTYPE="SMDR", @pCONFIG="Y" XXXXXXX
@pRUKE=dfgt@pRECTYPE="SBSB", @pGWID="1234", @pSBEL_MCTR_RSN="KX28", @pSBSB_9000_COLL=""
@pRUKE=dfgt@pRECTYPE="KBSG", @pKBSG_UPDATE_CD="IN", XXXXXXXXXXX
@pRUKE=dfgt@pRECTYPE="SBEL", @pSBEL_EFF_DT="01/01/2017", @pCSPI_ID="JKOX0001", @pSBEL_FI="A"
@pRUKE=dfgt@pRECTYPE="SBEK", @pSBEK_UPDATE_CD="IN",XXXXXXXXXXXXXXXXXXX
@pRUKE=dfgt@pRECTYPE="DBCS", @pDBCS_UPDATE_CD="IN",XXXXXXXXXXXXXXXXXXXXXXXXXX
@pRUKE=dfgt@pRECTYPE="MEME", @pMEME_REL="18", @pMEEL_MCTR_RSN="KX28"
@pRUKE=dfgt@pRECTYPE="ATT0", @pATT0_UPDATE_CD="AP",XXXXXXXXX
@pRUKE=dfgt@pRECTYPE="SBSB", @pGWID="1234", @pSBEL_MCTR_RSN="KX28", @pSBSB_9000_COLL=""
@pRUKE=dfgt@pRECTYPE="KBSG", @pKBSG_UPDATE_CD="IN", XXXXXXXXXXX
示例:
之前:
@pRUKE=dfgt@pRECTYPE="SMDR", @pCONFIG="Y" XXXXXXX
@pRUKE=dfgt@pRECTYPE="SBSB", @pGWID="1234", @pSBEL_MCTR_RSN="KX28", @pSBSB_9000_COLL=""
@pRUKE=dfgt@pRECTYPE="KBSG", @pKBSG_UPDATE_CD="IN", XXXXXXXXXXX
@pRUKE=dfgt@pRECTYPE="SBEL", @pSBEL_EFF_DT="01/01/2017", @pCSPI_ID="JKOX0001", @pSBEL_FI="A"
之后:
@pRUKE=dfgt@pRECTYPE="SMDR", @pCONFIG="Y" XXXXXXX
@pRUKE=dfgt@pRECTYPE="SBSB", @pGWID="1234", @pSBEL_MCTR_RSN="KX28", @pSBSB_9000_COLL=""
@pRUKE=dfgt@pRECTYPE="KBSG", @pKBSG_UPDATE_CD="IN", XXXXXXXXXXX
@pRUKE=dfgt@pRECTYPE="SBEL", @pSBEL_EFF_DT="01/01/2017", @pCSPI_ID="JKOX0001", @pSBEL_FI="A", @pSBEL_MCTR_RSN="KX28"
SBSB之后,如果没有SBEL,那么那个SBSB可以忽略。
我做的是:
egrep -n "pRECTYPE=\"SBSB\"|pRECTYPE=\"SBEL\"" filename | sed '$!N;/pRECTYPE=\"SBEL\"/P;D' | awk -F\: '{print }' | awk 'NR%2{printf "%s,",[=13=];next;}1' > 4.txt;
通过这个我将得到行号,例如:
2,4
17,19
第 9 12 14 行将被忽略
while read line
do
echo "$line";
SBSB=`echo "$line" | awk -F, '{print }'`;
SBEL=`echo "$line" | awk -F, '{print }'`;
echo $SBSB;
echo $SBEL;
SBSB_Fetch=`sed -n "$SBSB p" $fil | grep -Eo '(@pSBEL_MCTR_RSN)=[^ ]+' | sed 's/,$//' | sed 's/^/, /g'`;
echo $SBSB_Fetch;
if [[ "$SBSB_Fetch" == "" ]];then
echo "blank";
s=blank;
else
echo "value";
sed -i "${SBEL}s/.*/&${SBSB_Fetch}/" $fil;
fi
done < 4.txt;
由于我已经准备好并更新每一行,因此需要更多时间,有什么方法可以减少 运行 时间吗?
对于 70 Mb,现在需要 4 .5 小时。
为了提高性能,您确实需要限制在 shell 脚本的循环内调用的外部工具数量。
这需要 GNU awk:
gawk '
/@pRECTYPE="SBSB"/ {match([=10=], /@pSBEL_MCTR_RSN="[^"]*"/, m)}
/@pRECTYPE="SBEL"/ && isarray(m) {[=10=] = [=10=] ", " m[0]; delete m}
1
' file
这应该很快:
- 只调用一个外部命令
- 无shell 循环
- 只需读取一次输入文件。
我有以下要求。我正在尝试 运行 循环中的条件,这需要更多时间。是否有任何一次性命令不会花费更多时间来处理 70 MB 文件。
要求: 如果@pRECTYPE="SBSB" 行包含@pSBEL_MCTR_RSN="XXX" 标记,那么我们需要将其复制并附加到行末尾的下一个@pRECTYPE="SBEL 记录
文件 :note : 文件中不会有空行。我输入了 enter 以避免行继续
@pRUKE=dfgt@pRECTYPE="SMDR", @pCONFIG="Y" XXXXXXX
@pRUKE=dfgt@pRECTYPE="SBSB", @pGWID="1234", @pSBEL_MCTR_RSN="KX28", @pSBSB_9000_COLL=""
@pRUKE=dfgt@pRECTYPE="KBSG", @pKBSG_UPDATE_CD="IN", XXXXXXXXXXX
@pRUKE=dfgt@pRECTYPE="SBEL", @pSBEL_EFF_DT="01/01/2017", @pCSPI_ID="JKOX0001", @pSBEL_FI="A"
@pRUKE=dfgt@pRECTYPE="SBEK", @pSBEK_UPDATE_CD="IN",XXXXXXXXXXXXXXXXXXX
@pRUKE=dfgt@pRECTYPE="DBCS", @pDBCS_UPDATE_CD="IN",XXXXXXXXXXXXXXXXXXXXXXXXXX
@pRUKE=dfgt@pRECTYPE="MEME", @pMEME_REL="18", @pMEEL_MCTR_RSN="KX28"
@pRUKE=dfgt@pRECTYPE="ATT0", @pATT0_UPDATE_CD="AP",XXXXXXXXX
@pRUKE=dfgt@pRECTYPE="SBSB", @pGWID="1234", @pSBEL_MCTR_RSN="KX28", @pSBSB_9000_COLL=""
@pRUKE=dfgt@pRECTYPE="KBSG", @pKBSG_UPDATE_CD="IN", XXXXXXXXXXX
示例:
之前:
@pRUKE=dfgt@pRECTYPE="SMDR", @pCONFIG="Y" XXXXXXX
@pRUKE=dfgt@pRECTYPE="SBSB", @pGWID="1234", @pSBEL_MCTR_RSN="KX28", @pSBSB_9000_COLL=""
@pRUKE=dfgt@pRECTYPE="KBSG", @pKBSG_UPDATE_CD="IN", XXXXXXXXXXX
@pRUKE=dfgt@pRECTYPE="SBEL", @pSBEL_EFF_DT="01/01/2017", @pCSPI_ID="JKOX0001", @pSBEL_FI="A"
之后:
@pRUKE=dfgt@pRECTYPE="SMDR", @pCONFIG="Y" XXXXXXX
@pRUKE=dfgt@pRECTYPE="SBSB", @pGWID="1234", @pSBEL_MCTR_RSN="KX28", @pSBSB_9000_COLL=""
@pRUKE=dfgt@pRECTYPE="KBSG", @pKBSG_UPDATE_CD="IN", XXXXXXXXXXX
@pRUKE=dfgt@pRECTYPE="SBEL", @pSBEL_EFF_DT="01/01/2017", @pCSPI_ID="JKOX0001", @pSBEL_FI="A", @pSBEL_MCTR_RSN="KX28"
SBSB之后,如果没有SBEL,那么那个SBSB可以忽略。
我做的是:
egrep -n "pRECTYPE=\"SBSB\"|pRECTYPE=\"SBEL\"" filename | sed '$!N;/pRECTYPE=\"SBEL\"/P;D' | awk -F\: '{print }' | awk 'NR%2{printf "%s,",[=13=];next;}1' > 4.txt;
通过这个我将得到行号,例如:
2,4
17,19
第 9 12 14 行将被忽略
while read line
do
echo "$line";
SBSB=`echo "$line" | awk -F, '{print }'`;
SBEL=`echo "$line" | awk -F, '{print }'`;
echo $SBSB;
echo $SBEL;
SBSB_Fetch=`sed -n "$SBSB p" $fil | grep -Eo '(@pSBEL_MCTR_RSN)=[^ ]+' | sed 's/,$//' | sed 's/^/, /g'`;
echo $SBSB_Fetch;
if [[ "$SBSB_Fetch" == "" ]];then
echo "blank";
s=blank;
else
echo "value";
sed -i "${SBEL}s/.*/&${SBSB_Fetch}/" $fil;
fi
done < 4.txt;
由于我已经准备好并更新每一行,因此需要更多时间,有什么方法可以减少 运行 时间吗?
对于 70 Mb,现在需要 4 .5 小时。
为了提高性能,您确实需要限制在 shell 脚本的循环内调用的外部工具数量。
这需要 GNU awk:
gawk '
/@pRECTYPE="SBSB"/ {match([=10=], /@pSBEL_MCTR_RSN="[^"]*"/, m)}
/@pRECTYPE="SBEL"/ && isarray(m) {[=10=] = [=10=] ", " m[0]; delete m}
1
' file
这应该很快:
- 只调用一个外部命令
- 无shell 循环
- 只需读取一次输入文件。