# Tenth Line
**Difficulty:** EASY
[External](https://leetcode.com/problems/tenth-line)
Canonical: https://scaleengineer.com/dsa/problems/tenth-line
---
## Problem
Given a text file `file.txt`, print just the 10th line of the file.

**Example:**

Assume that `file.txt` has the following content:

Line 1
Line 2
Line 3
Line 4
Line 5
Line 6
Line 7
Line 8
Line 9
Line 10

Your script should output the tenth line, which is:

Line 10

**Note:**  
1\. If the file contains less than 10 lines, what should you output?  
2\. There's at least three different solutions. Try to explore all possibilities.

# Approaches
## Brute Force: Reading Entire File into Memory
This approach involves reading all lines from the file and storing them in a list in memory. Once the entire file is read, we can easily access the 10th line by its index if it exists.
**Time:** O(N), where N is the total number of characters in the file. The entire file must be read and parsed. · **Space:** O(N), where N is the total number of characters in the file. All lines are stored in memory.
**Pros:** Very simple to write and understand using modern Java APIs.; Provides random access to any line after the initial read.
**Cons:** Highly inefficient for large files, as it can consume a large amount of memory and potentially cause an `OutOfMemoryError`.; Unnecessary work is done by reading the entire file when only the 10th line is needed.
### Explanation
The simplest, but most memory-intensive, way to solve this is to read the whole file into a data structure, like an `ArrayList`. We can use Java's `Files.readAllLines()` method, which conveniently reads all lines from a file into a `List<String>`. After loading all lines, we check if the list contains at least 10 lines. If it does, we retrieve and print the element at index 9 (since lists are 0-indexed). If the file has fewer than 10 lines, the list size will be less than 10, and we do nothing, effectively handling the edge case.

```java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class ReadAllLines {
    public static void main(String[] args) {
        String fileName = "file.txt";
        try {
            List<String> allLines = Files.readAllLines(Paths.get(fileName));
            if (allLines.size() >= 10) {
                System.out.println(allLines.get(9));
            }
        } catch (IOException e) {
            System.err.println("Error reading file: " + e.getMessage());
        }
    }
}
```
### Algorithm
- Read all lines from `file.txt` into a `List<String>`.
- Check if the size of the list is 10 or more.
- If it is, print the string at index 9 of the list.
- If the file has fewer than 10 lines, or an error occurs, nothing is printed.

## Iterative Reading with a Counter
A more memory-efficient approach is to read the file line by line, keeping track of the current line number. We stop reading and print the line as soon as we reach the 10th line.
**Time:** O(L), where L is the number of characters up to the 10th line. In the worst case (file has fewer than 10 lines), it's O(N), where N is the total number of characters. For any file with at least 10 lines, this is constant time relative to the file size. · **Space:** O(M), where M is the maximum length of a line in the file. This is because we only need to store one line at a time. It's often considered O(1) or constant space.
**Pros:** Very memory efficient; suitable for files of any size.; Time efficient, as it stops reading as soon as the target line is found.
**Cons:** Slightly more verbose than the first approach.; Does not provide random access to other lines without re-reading the file.
### Explanation
This method avoids loading the entire file into memory. Instead, it processes the file as a stream. We use a `BufferedReader` to read the file one line at a time. A counter variable is initialized to 1 and incremented for each line read. When the counter equals 10, we've found our target line. We print it and can immediately stop processing the rest of the file by breaking the loop. If the loop finishes (i.e., we reach the end of the file) and the counter is less than 10, it means the file has fewer than 10 lines, and nothing is printed.

```java
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class IterativeRead {
    public static void main(String[] args) {
        String fileName = "file.txt";
        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            String line;
            int lineCount = 0;
            while ((line = reader.readLine()) != null) {
                lineCount++;
                if (lineCount == 10) {
                    System.out.println(line);
                    break; // Stop reading after the 10th line
                }
            }
        } catch (IOException e) {
            System.err.println("Error reading file: " + e.getMessage());
        }
    }
}
```
### Algorithm
- Initialize a line counter to 0.
- Open `file.txt` using a `BufferedReader`.
- Read the file line by line in a loop.
- For each line, increment the counter.
- If the counter reaches 10, print the current line and exit the loop.
- If the end of the file is reached before the counter hits 10, do nothing.

## Executing Shell Commands
For environments where shell tools are available (like Linux or macOS), the most idiomatic and often fastest solution is to delegate the task to specialized command-line utilities like `sed`, `awk`, or a combination of `head` and `tail`.
**Time:** O(L), where L is the number of characters up to the 10th line. The underlying native tools are highly optimized and stop processing early. · **Space:** O(1). The external process handles the file stream with minimal memory usage. The Java wrapper itself uses negligible memory.
**Pros:** Extremely concise and leverages highly optimized, battle-tested system tools.; Often the fastest practical solution.; Considered the standard 'scripting' solution for this type of problem.
**Cons:** Not platform-independent. It relies on the presence of specific shell commands (e.g., `sed`), making it unsuitable for pure-Java, cross-platform applications.; Adds complexity related to process management and error handling (e.g., command not found, shell errors).
### Explanation
This approach leverages the power and efficiency of standard Unix/Linux tools that are highly optimized for text processing. We can execute these commands from within a Java program.

- **`sed` (Stream Editor):** The command `sed -n '10p' file.txt` is perfect for this. `-n` suppresses default output, and `10p` prints only the 10th line.
- **`awk`:** The command `awk 'NR == 10' file.txt` works similarly. `NR` is the record (line) number, and the default action for a true condition is to print the line.
- **`head` and `tail`:** The pipeline `head -n 10 file.txt | tail -n 1` first takes the top 10 lines, then `tail` takes the last line from that output, which is the 10th line.

We can execute these from Java using the `ProcessBuilder` class, which allows us to run external commands and read their output.

```java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class ShellCommand {
    public static void main(String[] args) {
        // This assumes a Unix-like environment with 'sed' available.
        String[] command = {"/bin/sh", "-c", "sed -n '10p' file.txt"};
        try {
            ProcessBuilder pb = new ProcessBuilder(command);
            Process process = pb.start();

            // Read the output from the command
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                String line;
                if ((line = reader.readLine()) != null) {
                    System.out.println(line);
                }
            }

            process.waitFor(); // Wait for the process to finish
        } catch (IOException | InterruptedException e) {
            System.err.println("Error executing command: " + e.getMessage());
        }
    }
}
```
### Algorithm
- Construct a shell command string that extracts the 10th line (e.g., `sed -n '10p' file.txt`).
- Use Java's `ProcessBuilder` or `Runtime.getRuntime().exec()` to execute the command.
- Capture the standard output stream of the created process.
- Read the line from the output stream and print it to the console.
- Handle potential errors during process execution.
