Share four different solutions


  • 57
    T
    # Solution 1
    cnt=0
    while read line && [ $cnt -le 10 ]; do
      let 'cnt = cnt + 1'
      if [ $cnt -eq 10 ]; then
        echo $line
        exit 0
      fi
    done < file.txt
    
    # Solution 2
    awk 'FNR == 10 {print }'  file.txt
    # OR
    awk 'NR == 10' file.txt
    
    # Solution 3
    sed -n 10p file.txt
    
    # Solution 4
    tail -n+10 file.txt|head -1

  • 0
    Y

    cool, I just use the same sed code to solve it


  • 20
    G

    From an efficiency standpoint, wouldn't you want to exit once you've printed the 10th line?

    The awk and sed solutions do not exit immediately after printing. So in case of a large file, they will print the 10th line, but then keep on looping until the end of file.

    For my testcase, I created a file that has 100 million lines. And then I use the "time" command to time each solution. Notice that Solutions 1 and 4 are very fast - less than a second, but solutions 2 and 3 take up anywhere from 12 to 19 seconds, which is an unnecessary time hog.

    The last two awk scripts exit right after printing and you can see that their run times have improved.
    I don't know the equivalent for sed.

    (Also, I replaced the "exit 0" in the shell script by a "return", which returns control to the shell prompt but does not close the terminal window.)

    $
    $ head file.txt
    Line 1
    Line 2
    Line 3
    Line 4
    Line 5
    Line 6
    Line 7
    Line 8
    Line 9
    Line 10
    
    $ tail file.txt
    Line 99999991
    Line 99999992
    Line 99999993
    Line 99999994
    Line 99999995
    Line 99999996
    Line 99999997
    Line 99999998
    Line 99999999
    Line 100000000
    
    $
    $ wc file.txt
     100000000  200000000 1388888898 file.txt
        
    $
    $ # Solution 1
    $ cat print_tenth_line.sh
    cnt=0
    while read line && [ $cnt -le 10 ]; do
      let 'cnt = cnt + 1'
      if [ $cnt -eq 10 ]; then
        echo $line
        #exit 0
        return
      fi
    done < file.txt
    
    $ time . print_tenth_line.sh
    Line 10
    
    real    0m0.000s
    user    0m0.000s
    sys     0m0.000s
    
    $
    $ # Solution 2
    $ time awk 'FNR == 10 {print }'  file.txt
    Line 10
    
    real    0m15.397s
    user    0m15.007s
    sys     0m0.342s
    
    $
    $ time awk 'NR == 10' file.txt
    Line 10
    
    real    0m12.683s
    user    0m12.151s
    sys     0m0.498s
    
    $
    $ # Solution 3
    $ time sed -n 10p file.txt
    Line 10
    
    real    0m19.750s
    user    0m19.328s
    sys     0m0.405s
    
    $ # Solution 4
    $ time tail -n+10 file.txt|head -1
    Line 10
    
    real    0m0.062s
    user    0m0.000s
    sys     0m0.061s
    
    $
    $ # ==========  Efficient awk ==========
    $ time awk 'NR==10{print; exit}' file.txt
    Line 10
    
    real    0m0.031s
    user    0m0.000s
    sys     0m0.030s
    
    $ time awk 'FNR==10{print; exit}' file.txt
    Line 10
    
    real    0m0.031s
    user    0m0.000s
    sys     0m0.030s
    
    $
    $
    

  • 1
    A

    When you use sed knowing when to exit, you should quit explicitly like this:

    sed -n '10p;11q' file.txt
    

    Would you like to test it again?


Log in to reply
 

Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.