【问题标题】:How to use while read line with tail -n如何在使用tail -n读取行时使用
【发布时间】:2016-02-05 18:09:14
【问题描述】:

问题:我有一个 CSV 转储文件 - 超过 250,000 行。当我使用while read 时 - 需要一段时间(没有双关语)。我想回到最后 10,000 行来做我需要做的事情,而不是 250,000 行。

代码片段:我当前的代码是这样的:

IFS=","
while read line
do

    awk_var=`echo "$line" | awk -F" " '{print $0}'`

    var_array=($awk_var)

    read -a var_array <<< "${awk_var}"

    echo "${var_array[1]}"


done </some_directory/directory/file_in_question.csv

问题:在使用 bash 脚本读取 file_in_question.csv 时,如何使用 tail -n10000while read line

【问题讨论】:

  • {print $0}{print} 到 awk 相同,这与根本不使用 awk 相同。你想在那里做什么?这里的时间很可能是从 250,000 次调用到awk(每个循环一次)。如果可以,请避免使用这些。
  • @EtanReisner 嗯,第一个参数是以秒为单位的 Unix 时间戳,所以,我计算一个边界(两个日期/时间戳),并在上述边界之间提取数据。做这样的事情可以使我的代码更快的替代方法是什么?
  • 我的意思是awk_var=$(echo "$line" | awk -F " " '{print $0}')awk_var=$(echo "$line") 完全相同,这与awk_var=$line 完全相同,这与首先使用$line 相同,只是少了两个外部命令,少一个子shell和几行代码。同样var_array=($awk_var) 是错误的,您稍后用read 覆盖awk_var

标签: bash csv while-loop tail


【解决方案1】:

替换:

done </some_directory/directory/file_in_question.csv

与:

done < <(tail -n10000 /some_directory/directory/file_in_question.csv)

&lt;(...) 构造称为进程替换。它创建了一个 bash 可以读取的类文件对象。因此,这将直接从 some_directory/directory/file_in_question.csv 读取替换为从 tail -n10000 /some_directory/directory/file_in_question.csv 读取。

使用这样的进程替换可以让您将 while 循环保留在主 shell 中,而不是子 shell 中。因此,您在while 循环中创建的变量将在循环退出后保留其值。

加速原代码

所示代码打印 CSV 文件的第二列。如果这就是代码应该做的全部,那么它可以替换为:

awk -F, '{print $2}' /some_directory/directory/file_in_question.csv

【讨论】:

  • 谢谢约翰,只是一个简短的问题 - 使用 MyVar=$(some_command) ie GetTodaysDate=$(date +%F) 是否也考虑了进程替换
  • @3kstc 不,那是命令替换。不同之处在于 command 替换捕获进程的标准输出,而 process 替换生成类似文件的对象。
  • 哦,那是正确的,我很抱歉 - 我把我的替换弄混了:S!
  • 在这种情况下如何在阅读时退出?编辑:nvm,只需在循环中添加“break”命令。
【解决方案2】:

类似:

IFS=","
tail /var/log/httpd/error_log | while read foo bar
do
    echo $foo
done

我建议您在 bash 中使用 read 进行拆分,而不是在那里低效地调用 awk。显然,将整个东西重写为 awk 脚本会比 shell 更快,但 awk 是更难的不太常见的语言。

【讨论】:

    【解决方案3】:

    或者这个。

    while : 
    do read l || { sleep 1 ; continue; }
       echo "==> $l"
    done < /var/log/httpd/error_log
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-15
      • 2014-10-31
      • 2017-11-14
      • 2017-03-21
      • 2019-04-07
      • 1970-01-01
      • 1970-01-01
      • 2017-03-31
      相关资源
      最近更新 更多