7

How can I prepend some custom text when opening a file in less? For example, I would like to see something like:

My custom title

Content of the opened file goes here...

I want a command for that like:

echo 'My custom title' | less file

less does not have this feature. But it must be possible to achieve with some workaround. Basically, we need to sequentially combine two files into one and then open it. How can I create a temporary virtual file in RAM that will contain this new file to open in less?

Similar question:

3 Answers 3

15

Why not

( echo 'My custom title'; cat file ) | less

Drop it into a function if you want it available interactively; this version takes precisely one file name (plus any less options you may want to provide):

# bash
myless() {
    local x=("$@")
    local f="${x[-1]}"
    unset x[-1]
    { echo 'My custom title'; cat "$f"; } | less "${x[@]}"
}

For a more specific scenario you can modify the function appropriately. For example, if the first argument is a header and the second is always a file, you could vastly simplify like this:

myless() {
    { printf '%s\n' "$1"; cat -- "$2"; } | less
}

If you want the header to be the file name, it would seem more sensible to use the options already in less to provide this on the prompt line. But alternatively,

myless() {
    while [ "$#" -gt 0 ]
    do
        printf '\n\n%s\n' "$1"
        cat -- "$1"
        shift
    done |
        less
}
4
  • That is great. Thank you. You solution is better than my because it is much simpler and allows to pass parameters to less. Title also can be separated with \n\n in echo with -e flag: (echo -e '/mnt/tmpfs/clipboard content:\n\n'; cat /mnt/tmpfs/clipboard) | less Commented Apr 8 at 16:31
  • 1
    The first example spawns a useless subshell (maybe you forgot to change that as you used braces in the actual function definition); also not the cleanest either but maybe a bit less ugly than echo / printf + cat: cat -- - "$2" <<<"$1"$'\n' | less
    – kos
    Commented Apr 8 at 17:12
  • 1
    @AntonSamokat x is an array (a list). The -1 element of a list is its last element. unset deletes the named variable (or variable[index]) Commented Apr 8 at 22:12
  • Description of other constructions: () {}, "${x[@]}", --, -, shift, $# Commented Apr 9 at 19:24
6

The usual, sub-shell based approach:

(echo "custom title"; cat file) | less

works.

I do like my vim (or neovim), so I do things like

#!/bin/ksh
# or /bin/bash or /usr/bin/zsh, really
open_with_title() {
  title="$1"
  shift
  ${EDITOR:-vim} \
       --clean \
       -R \
       --cmd ':set showtablines=2' \
       --cmd ":set tabline='${title}'" \
       -- \
       $@
}

To use vim's "viewer" mode, and set the title of the view. (To prevent confusion, if you've never used ed or vi or derivatives: you'll type :q to quit.)

-3

Setup RAM partition as described here: shell script - How to make a temporary file in RAM? - Unix & Linux Stack Exchange

Add function for opening less with title to .bashrc or .bash_funcs.sh:

open_less_with_title() { 
    local title="$1"
    local file="$2"
    local tmp_dir=""
    local virtual_tmp_dir="/mnt/tmpfs"
    if [ -d "$virtual_tmp_dir" ]; then
        tmp_dir="$virtual_tmp_dir"
    else
        tmp_dir="/tmp"
    fi
    tmp_less_file=$(mktemp "$tmp_dir/tmp_less_file.XXXXXXXXXX")
    echo -e "$title\n\n" > "$tmp_less_file"
    cat "$file" >> "$tmp_less_file"
    less "$tmp_less_file"
    rm "$tmp_less_file"
}

Example of usage:

open_less_with_title "My custom title" /path/to/file
11
  • 2
    I'd recommend that you replace tmp_less_file="/mnt/tmpfs/tmp_less_file"; with tmp_less_file="$(mktemp --tmpdir less_tmp_XXX)" and add a rm "${tmp_less_file}" to the end. Commented Apr 8 at 16:49
  • 2
    @AntonSamokat that depends on your system. In many cases, /tmp is indeed in RAM. That's the default on Arch, for instance, and on the system I am writing this comment from, my /tmp is in RAM.
    – terdon
    Commented Apr 8 at 17:01
  • 2
    @AntonSamokat what terdon said, also, the moment you write to a file and then immediately open it the next moment for reading, chances are it's still in the in-RAM caches, anyways; Linux (and generally, all modern operating systems) are smart like that and buffers in RAM for as long as there's no memory demand that makes it necessary to flush them out. Plus, honestly, you're doing things with less. How many GB of a single text file are you going to look at that your storage speed is going to matter to you, a human? Commented Apr 8 at 17:03
  • 2
    that's not a solution; if you run things in parallel, a second is very long, you're not solving anything: really, use mktemp to generate as safe filename. man mktemp is you friend. And again, your /mnt/tmpfs thing is probably superfluous, maybe even worse than simply using mktemp's default location. Commented Apr 8 at 17:37
  • 3
    this is really just unnecessary. But you do you, I guess. Commented Apr 8 at 23:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .