How to Use Tail Command with Wildcards for Multiple Files Ending with “-access_log”


2 views

When working with log files in Linux/Unix systems, a common pattern is needing to view the last few lines of multiple similarly-named files. Many developers encounter this specific issue when trying to use wildcards with the tail command for files ending with "-access_log".

The command tail -10 *-access_log fails while tail -10 file-* works because of how shell expansion handles patterns at the beginning versus end of filenames. The wildcard position affects how the shell processes the command.

Here are three reliable approaches to view the last 10 lines of multiple "-access_log" files:

# Solution 1: Use the -- option
tail -10 -- *-access_log

# Solution 2: Explicit path specification
tail -10 ./**/*-access_log

# Solution 3: Using find + xargs
find . -name "*-access_log" -print0 | xargs -0 tail -10

The -- option tells tail to treat all following arguments as filenames, even if they start with a dash. This solves the shell expansion issue when dealing with patterns at the beginning of filenames.

Consider this directory structure with multiple access logs:

/var/log/
├── app1-access_log
├── app2-access_log
└── app3-access_log

To view the last 15 lines of all these files:

cd /var/log
tail -15 -- *-access_log

For recursive searching through subdirectories:

shopt -s globstar
tail -10 **/*-access_log

For very large directories with thousands of matching files, the find/xargs approach is more efficient as it handles filename limitations better:

find /var/log -type f -name "*-access_log" -exec tail -10 {} +

Persistent solutions can be added to your shell configuration:

alias tailogs='tail -10 -- *-access_log'

Many Linux users encounter this issue when trying to view the last lines of multiple log files with similar naming patterns. The command:

tail -10 *-access_log

fails with an error, while:

tail -10 file-*

works as expected. This behavior seems inconsistent, especially since commands like:

cat *-access_log

work perfectly fine.

The root cause lies in how the shell handles wildcard expansion before passing arguments to commands. When you use:

tail -10 *-access_log

The shell first expands the wildcard, then passes all matching files to tail. If you have many matching files, this can exceed the maximum argument limit.

Here are several ways to solve this problem:

1. Using xargs

This approach handles large numbers of files efficiently:

find . -name "*-access_log" -print0 | xargs -0 tail -n 10

2. Using a Loop

For more control over the output:

for file in *-access_log; do
    echo "=== $file ==="
    tail -n 10 "$file"
done

3. Using Shell Options

You can modify shell behavior to handle large argument lists:

ulimit -S -s unlimited
tail -n 10 *-access_log

If you frequently need to monitor multiple log files, consider these alternatives:

# Using multitail
multitail -n 10 *-access_log

# Using tail with --follow=name
tail -n 10 -f *-access_log

When working with multiple log files:

  • Always test wildcard patterns with echo first
  • Consider using more specific patterns (e.g., *-access_log.2023*)
  • For large directories, use find instead of shell globbing
  • Add separators between files when outputting multiple tails