Как записать каждую строку результата вызова system () в список в Vimscript? - PullRequest
5 голосов
/ 20 июня 2011

Я бы хотел зациклить файлы в каталоге, используя Vimscript. Чтение usr_41.txt и поиск по всему, лучшее, что я могу придумать, это что-то вроде let dir_contents = system('ls')

Но поскольку system() не возвращает список, я не могу зациклить его. Есть ли способ сохранить результаты системного вызова в виде списка, или команда или функция Vim, которая уже делает это?

Ответы [ 5 ]

4 голосов
/ 20 июня 2011

Вы можете получить список с помощью split(system('ls'), '\n'), который даст вам список файлов, если у вас нет файлов с символами новой строки в них.

1 голос
/ 06 января 2018

Я только что обнаружил, что в этих ответах есть тонкость:

В настоящее время (январь 2018 г.) у vim есть systemlist (), который удовлетворит ваши потребности:

let l:ls=systemlist("ls")
" or let dir_contents=etc etc

Однако, если вы делаете что-то, кроме «ls», вы можете столкнуться со странным хитрым поведением: завершающие пустые строки будут отброшены (по состоянию на январь 2018 года).Если это не проблема, не беспокойтесь, используйте systemlist () и будьте счастливы.Если это проблема, вы, вероятно, захотите сделать что-то вроде этого:

let l:myvar=system("myprogram -that -returns -blank -lines")
l:mylist=split(l:myvar, "\n", 1) " the 1 is to keep empty lines

Надеюсь, что это кому-нибудь поможет!

1 голос
/ 21 июня 2011

Есть встроенная функция glob(). Чтобы получить список файлов в текущем каталоге Windows, вы можете использовать split(glob('.\\*'), "\n"). На * nix все намного сложнее, чем на

  1. POSIX позволяет всем, кроме NULL, находиться в имени файла. Здесь все означает, что перевод строки ("\ n") также разрешен.
  2. glob() функция не возвращает имена файлов, начинающиеся с точки, если явно не запрошено (используя glob('dir/.*')).
  3. Когда явно запрашивается список имен файлов, начинающихся с точки, glob() также показывает . (текущий каталог) и .. (родительский каталог) специальные каталоги.

Чтобы решить эту проблему, вы должны использовать что-то вроде this (или использовать vim с поддержкой python и собственной функцией os.listdir python).

Если вы не против иметь frawor в зависимостях, вы можете сделать следующее:

execute frawor#Setup('0.0', {'@/os': '0.0'})
<...>
let dir_contents=s:_r.os.listdir('.')

О получении списка строк из команды оболочки: если вы знаете, что запускаемая команда не будет выводить значения NULL, вы можете использовать split(system(cmd), "\n", 1) (возможно, без последнего аргумента, если вам не нужны пустые строки). Если вы знаете, что команда может выдавать значения NULL и хотите сохранить их, вам нужно проделать дополнительную работу:

noautocmd new
read !cmd
let s:shell_output=getline(2, line('$'))
noautocmd bwipeout!

Обратите внимание, что в этом случае значения NULL будут заменены символами новой строки в списке s:shell_output, тогда как фактические символы новой строки будут представлены как концы строк.

1 голос
/ 20 июня 2011

Попробуйте что-то вроде

split(system('ls', nr2char(10))

В настоящее время я не нахожусь в системе Unix, поэтому я не могу попробовать сам, но она работает в Windows (и dir), например

for FILE in split(system('dir /b', nr2char(10))
  echo 'File is: ' . FILE
endfor
0 голосов

системный список добавлен в Vim 7.4: 248 делает именно то, что вы хотите:

:echo systemlist('printf "a\nb\n"')

выход:

['a', 'b']

Из документов http://vimhelp.appspot.com/eval.txt.html#eval.txt

systemlist({expr} [, {input}])                          systemlist()
                Same as system(), but returns a List with lines (parts of 
                output separated by NL) with NULs transformed into NLs. Output 
                is the same as readfile() will output with {binary} argument 
                set to "b".

                Returns an empty string on error.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...