Bash Shell脚本(在循环中运行sed)未完成大文件
下面是我将转换后的数据转换成新文件的代码Bash Shell脚本(在循环中运行sed)未完成大文件,bash,shell,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 d
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
预期产出为:
Fri Feb 20 11:31:49 2015,ABC
Fri Feb 20 10:12:32 2015,XYZ
Fri Feb 20 14:58:53 2015,DEF
看看上面的代码和文件,我想我们清楚需要什么。我只想把长格式的日期转换成日期格式。代码运行良好。如果我有少量的行,那么根本就没有问题。我目前正在处理一个有150000条记录的大文件。代码被卡住了,根本不退出。任何人都可以帮我解决我在这里遗漏的问题。您可以用一种稍微简单(且更快)的方法来处理,只需修改一次文件,但使用多个
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"
这就足够了(可能是条形时区)。您可以用一种稍微简单一点(也快得多)的方法来处理它,只需修改一次文件,但使用多个
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"
这看起来很像,但是如果我们假设报告包含多个时间戳,并且您想要转换所有时间戳,那么可以尝试
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
(再加上另一次通读以读取时间戳),这应该比脚本快得多,脚本会为文件中的每一行重写整个文件一次,有时是不必要的。这看起来很像,但如果我们假设报告包含多个时间戳,并且您希望转换所有时间戳,那么可以尝试
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
(再加上另一次通读以读取时间戳),这应该比脚本快得多,脚本会为文件中的每一行重写整个文件一次,有时是不必要的。感谢您的帮助:)
我按照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
谢谢你的帮助:)
我按照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
我想,
$comp1
是多余的。除此之外,其余的看起来不错。它可能是ssboetod
不工作吗?当数据是10行时,它就工作了。如果它那么长,可能执行命令需要很长时间。试着在每次迭代中打印一些东西,看看它是否很慢。这样你就能知道是速度还是其他原因。还有,什么是ssboetod
?如果它是一个需要时间的外部命令,这可能是问题所在。@程序员,也许可以尝试使用我所做的,例如类似于$(date+'%a%m%d%H:%m:%S%Y'-d@$timestamp)
直接,而不是ssboetod
的说法,顺便说一句,代码被“卡住”是完全错误的。如果您给它足够的时间/天/年运行,它将退出。如果您使用bash-xyourscript
运行脚本,或者添加echo命令以登录到stderr,您会看到它正在运行,而不是真正卡住。我想$comp1
是多余的。除此之外,其余的看起来不错。它可能是ssboetod
不工作吗?当数据是10行时,它就工作了。如果它那么长,可能执行命令需要很长时间。试着在每次迭代中打印一些东西,看看它是否很慢。这样你就能知道是速度还是其他原因。还有,什么是ssboetod
?如果它是一个需要时间的外部命令,这可能是问题所在。@程序员,也许可以尝试使用我所做的,例如类似于$(date+'%a%m%d%H:%m:%S%Y'-d@$timestamp)
直接,而不是ssboetod
的说法,顺便说一句,代码被“卡住”是完全错误的。如果您给它足够的时间/天/年运行,它将退出。如果您使用bash-x yourscript
运行脚本,或者添加echo命令以登录到stderr,您会看到它正在做一些事情,而不是真正卡住。事实上,要获得时间戳
,在IFS=“,”读取时间戳rest时只说,速度会更快,然后,$timestamp
将包含第一列。。虽然我想让它看起来像原来的一样,但这只会替换文件最后一行的时间戳。需要更多的引号才能正确<代码>回显“$line”
,而不是回显$line
cp“$infle”
,等等。事实上,要获得时间戳
,只需说,而IFS=“,”读取时间戳rest
,然后$timestamp
将包含第一列。是的。。虽然我想让它看起来像原来的一样,但这只会替换文件最后一行的时间戳。需要更多的引号才能正确<代码>回显“$line”,而不是回显$line
cp“$infle”
等。是的,问题类似,我的处理方式基于您的答复本身。但我这里的问题不在于代码的工作。记录数少了,一切都好。问题出现在超过10万行的地方。就像@NickB所建议的,剩下的瓶颈可能是外部实用程序。请改用date
。但是,使用单个sed
脚本而不是重写文件100000次,应该已经快得多了。另外,请注意,在您所在地区以外的地方,您还不能广泛理解这些脚本。@程序员,您的原始脚本与输入长度类似于O(n^2)