Shell脚本(在循环中运行sed)没有用大文件完成

时间:2015-02-23 12:00:06

标签: bash shell

以下是我将转换后的数据转换为新文件的代码。

cat Report.csv > /tmp/report.part

while read line
do
comp1=$(echo $line | awk -F, '{print $1}')
timestamp=$(echo $line | awk -F, '{print $1}')
converted=$(ssboetod "$timestamp")
sed -i "s/$timestamp/$converted/g" Report.csv
done < /tmp/report.part

我的输入文件包含以下数据:

1424412109,ABC
1424407352,XYZ
1424424533,DEF

预期输出为:

Fri Feb 20 11:31:49 2015,ABC
Fri Feb 20 10:12:32 2015,XYZ 
Fri Feb 20 14:58:53 2015,DEF 

查看上面的代码和文件,我想我们很清楚需要什么。我只想将长格式日期转换为日期格式。代码工作正常。如果我的行数很少,则根本没有问题。我目前正在处理一个包含150,000条记录的大文件。代码卡住了,根本没有退出。任何人都可以帮助我解决我在这里错过的问题。

3 个答案:

答案 0 :(得分:3)

这看起来与an earlier question of yours非常相似,但是如果我们假设报告包含多个时间戳并且您想要转换所有这些时间戳,那么可以尝试

cut -d, -f1 Report.csv |
sort -u |
while read timestamp; do
    converted=$(ssboetod "$timestamp")
    echo "s/$timestamp/$converted/"
done |
sed -i -f - Report.csv

...假设您的sed可以容忍-f -从标准输入读取脚本(并非所有变体都可以这样做,但Linux应该没问题。)

通过从开始到结束只打开,读取和写回Report.csv一次(加上另一个读取读取时间戳),这应该比你的脚本快得多,后者每次重写一次整个文件文件中的行,有时是不必要的。

答案 1 :(得分:1)

您可以通过稍微修改文件一次,但使用多个sed替换来实现更简单(更快)的方式:

#! /bin/bash
infile='Report.csv'

while read line
do
    timestamp=$(echo "$line" | awk -F, '{print $1}')
    converted=$(ssboetod "$timestamp")
    script="s/$timestamp/$converted/g; $script"
done < "$infile"

cp "$infile" .backup.csv
sed -i -e "$script" "$infile"

我不得不猜测你ssboetod做了什么,所以对于我用过的测试:

converted=$(date +'%a %m %d %H:%M:%S %Y' -d @$timestamp)

工作得足够近(可能是吧时区)。

答案 2 :(得分:0)

感谢您的帮助:)

我按照tripleee的建议改变了我的while循环。下面给出的代码是完美的,并且在几秒钟内也会延迟。

cut -d, -f1 Report.csv |
sort -u |
while read timestamp; do
    converted=$(ssboetod "$timestamp")
    echo "s/$timestamp/$converted/"
done |
sed -i -f - Report.csv