试图调试服务器的一个问题,我唯一的日志文件是一个20GB的日志文件(甚至没有时间戳!)为什么人们使用System.out.println()作为日志?在生产吗? !)

使用grep,我找到了我想要查看的文件区域,第347340107行。

除了做一些

head -<$LINENUM + 10> filename | tail -20 

... 这将需要头读取日志文件的前3.47亿行,是否有一个快速而简单的命令将行347340100 - 347340200(例如)转储到控制台?

我完全忘记了grep可以打印匹配前后的上下文…这很有效。谢谢!


当前回答

要通过<line#>显示<textfile>中的一行,只需这样做:

perl -wne 'print if $. == <line#>' <textfile>

如果你想用更强大的方法用正则表达式来显示一行范围——我不会说为什么grep是一个坏主意,这应该是相当明显的——这个简单的表达式将在一次传递中显示你的范围,这是你在处理~20GB文本文件时想要的:

perl -wne 'print if m/<regex1>/ .. m/<regex2>/' <filename>

(提示:如果你的regex中有/,使用类似m!<regex>!相反)

这将打印出<filename>,从匹配<regex1>的行开始,直到(并包括)匹配<regex2>的行。

不需要一个向导,就可以看到一些调整可以使它更加强大。

最后一点:perl,因为它是一种成熟的语言,有许多隐藏的增强来提高速度和性能。考虑到这一点,它成为这种操作的明显选择,因为它最初是为处理大型日志文件、文本、数据库等而开发的。

其他回答

是什么:

tail -n +347340107 filename | head -n 100

我没有测试,但我认为这是可行的。

我更喜欢更少的

输入50%到文件的一半, 43210G转到43210行 :43210来做同样的事情

诸如此类。

更好的方法是:点击v以在该位置开始编辑(当然是在vim中!)现在,请注意vim具有相同的键绑定!

基于Sklivvz的回答,这里有一个可以放入.bash_aliases文件中的很好的函数。当从文件的前面打印东西时,它对巨大的文件是有效的。

function middle()
{
    startidx=$1
    len=$2
    endidx=$(($startidx+$len))
    filename=$3

    awk "FNR>=${startidx} && FNR<=${endidx} { print NR\" \"\$0 }; FNR>${endidx} { print \"END HERE\"; exit }" $filename
}

简单的perl!如果你想从文件中获得第1、3和5行,输入/etc/passwd:

perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd

打印行5

sed -n '5p' file.txt
sed '5q' file.txt

打印第5行以外的所有内容

`sed '5d' file.txt

我用谷歌创建的

#!/bin/bash
#removeline.sh
#remove deleting it comes move line xD

usage() {                                 # Function: Print a help message.
  echo "Usage: $0 -l LINENUMBER -i INPUTFILE [ -o OUTPUTFILE ]"
  echo "line is removed from INPUTFILE"
  echo "line is appended to OUTPUTFILE"
}
exit_abnormal() {                         # Function: Exit with error.
  usage
  exit 1
}

while getopts l:i:o:b flag
do
    case "${flag}" in
        l) line=${OPTARG};;
        i) input=${OPTARG};;
        o) output=${OPTARG};;
    esac
done

if [ -f tmp ]; then
echo "Temp file:tmp exist. delete it yourself :)"
exit
fi

if [ -f "$input" ]; then
   re_isanum='^[0-9]+$'
   if ! [[ $line =~ $re_isanum ]] ; then
      echo "Error: LINENUMBER must be a positive, whole number."
      exit 1
   elif [ $line -eq "0" ]; then
      echo "Error: LINENUMBER must be greater than zero."
      exit_abnormal
   fi
   if [ ! -z $output ]; then
      sed -n "${line}p" $input >> $output
   fi
   if [ ! -z $input ]; then
      # remove this sed command and this comes move line to other file
      sed "${line}d" $input > tmp && cp tmp $input
   fi
fi

if [ -f tmp ]; then
rm tmp
fi