Richard
Richard

Reputation: 15562

how to use vim to open every .txt file under a directory (with Bash)

I am trying the following to use a vim to open every txt file under current directory.

find . -name "*.txt" -print | while read aline; do
  read -p "start spellchecking fine: $aline" sth
  vim $aline
done

Running it in bash complains with

Vim: Warning: Input is not from a terminal
Vim: Error reading input, exiting...
Vim: Finished.

Can anyone explain what could possibly goes wrong? Also, I intend to use read -p for prompt before using vim, without no success.

Upvotes: 7

Views: 1852

Answers (4)

gniourf_gniourf
gniourf_gniourf

Reputation: 46823

The proper way to open all files in one single vim instance is (provided the number of files doesn't exceed the maximal number of arguments):

find . -name '*.txt' -type f -exec vim {} +

Another possibility that fully answers the OP, but with the benefit that it is safe regarding file names containing spaces or funny symbols.

find . -name '*.txt' -type f -exec bash -c 'read -p "start spellchecking $0"; vim "$0"' {} \;

Upvotes: 0

ZyX
ZyX

Reputation: 53604

With shopt -s globstar you can purge out find and thus make bash not execute vim in a subshell that receives output from find:

shopt -s globstar
shopt -s failglob
for file in **/*.txt ; do
    read -p "Start spellchecking fine: $file" sth
    vim "$file"
done

. Another idea is using

for file in $(find . -name "*.txt") ; do

(in case there are no filenames with spaces or newlines.)

Upvotes: 1

kguest
kguest

Reputation: 3844

Often the simplest solution is the best, and I believe this is it:

vim -o `find . -name \*.txt -type f`

The -type f is to ensure only files ending .txt are opened as you don't discount the possibility that there may be subdirectories that have names that end in ".txt".

This will open each file in a seperate window/bufer in vim, if you don't require this and are happy with using :next and :prefix to navigate through the files, remove "-o" from the suggested comand-line above.

Upvotes: 0

William Pursell
William Pursell

Reputation: 212238

Try:

vim $( find . -name "*.txt" )

To fix your solution, you can (probably) do:

find . -name "*.txt" -print | while read aline; do
      read -p "start spellchecking fine: $aline" sth < /dev/tty
      vim $aline < /dev/tty
done

The problem is that the entire while loop is taking its input from find, and vim inherits that pipe as its stdin. This is one technique for getting vim's input to come from your terminal. (Not all systems support /dev/tty, though.)

Upvotes: 13

Related Questions