1

I am using ArchLinux and I want to run some ex commands. The following outputs nothing on my system:

$ ex -s -c %p -c q /etc/hosts

The ex command is a part of vi package on my system:

$ pacman -Ql vi
vi /usr/bin/ex
vi /usr/bin/vi
...
$ pacman -Q vi
vi 1:070224-6
$ ex --help
ex: illegal option -- -
Usage: ex [- | -s] [-l] [-L] [-R] [-r [file]] [-t tag]
       [-v] [-V] [-w size] [+cmd | -c cmd] file...

In comparison, on my friends PC, ex is a symlink to vim:

$ ex --help | head
VIM - Vi IMproved 8.0 (2016 Sep 12)

usage: vim [arguments] [file ..]       edit specified file(s)
   or: vim [arguments] -               read text from stdin
   or: vim [arguments] -t tag          edit file where tag is defined
   or: vim [arguments] -q [errorfile]  edit file with first error

Arguments:
   --                   Only file names after this
   -v                   Vi mode (like "vi")
$ ex -s -c %p -c q /etc/hosts | wc
     29      92     935

How to output the buffer using ex from vi package, not using ex from vim? What is the difference? Why does ex from vi does not work as expected?


What kind of modification are you trying to do?

I am generating tags file for m4 file. Consider the following gentags.sh script:

#!/bin/bash
set -euo pipefail

has() { hash "$@" 2>/dev/null; }
fatal() { echo "$(basename "$0"): $*" >&2; exit 123; }


if (($#)); then
        method=$1
elif has nvim; then
        method=nvim
elif has ex; then
        method=ex
elif has vi; then
        method=vi
elif has vim; then
        method=vim
else
        fatal "no method, choose ex, vi, vim or nvim"
fi

case "$method" in
        ex) vi=(ex -s) ;;
        vi) vi=(vi -s) ;;
        vim) vi=(vim -EsR) ;;
        nvim) vi=(nvim -EsR) ;;
        *) fatal "Internal error" ;;
esac

export LC_ALL=C
rgx='\m^\s*m4_define\w*(\_s*«'
cmd=(
        "${vi[@]}"
        -c         'g!/'"$rgx"'\(\w*\)\>.*/d'
        -c '%s//\1\t\t\/'"${rgx//'\'/'\\'}"'\\zs\1\\>\/;"/'
        -c '%s/\t\zs\ze\t/\=expand("%")/'
        -c '%sort u'
        -c "w ./tags"
        -c 'q!'
        ./test.m4
)
set -x
rm -fv ./tags
"${cmd[@]}"
wc ./tags
head ./tags

Given test.m4 with the following content:

m4_define(«a», «b»)

Running ./gentags.sh nvim results in ./tags file with the following content:

a       ./test.m4       /\m^\s*m4_define\w*(\_s*«\zsa\>/;"

However, running ./gentags ex or vi or vim does not work, neither with -c "w ./tags" or with -c %p and redirection.

Would sed serve your purposes?

No, sed does not really have good support for multiline regexes. \_s* is perfecr for me use-case, and the same vi regex can be re-used inside tags file.

5
  • Why not just use cat?
    – Heptite
    Commented Jun 6 at 23:12
  • Because I want to run ex script, and then output the result of modying a file. I can :w save the file, but I am not able to ouptut it to stdout.
    – KamilCuk
    Commented Jun 7 at 8:27
  • What kind of modification are you trying to do? Would sed serve your purposes?
    – Heptite
    Commented Jun 10 at 1:42
  • @Heptite I edited the question with the underlying XY problem. If you feel like it, let me know if it's better to ask a separate question. The issue is however the same - neither ex -c %p (and neither ex -c w./tags) do not work in my environment.
    – KamilCuk
    Commented Jun 10 at 7:22
  • Since it remains unanswered here, have you tried vi.stackexchange.com? Commented Jun 10 at 8:46

0

You must log in to answer this question.

Browse other questions tagged .