Используйте расширенную подстановку для вывода списка файлов, но не каталогов в bash.

Вы передаете в сценарий фрагмент кода оболочки. Для сценария это просто текст. Чтобы его можно было интерпретировать как полноценную команду оболочки, вам нужно eval it:

eval "$1" >file1.tmp
eval "$2" >file2.tmp

Это работает, когда $ 1 и $ 2 - простые вещи например, echo hello , потому что это простые команды (не списки или составные команды).

Можно провести аналогию с другим языком программирования, если бы вы передали часть кода C в программу C в виде текстовой строки. Код должен быть каким-то образом скомпилирован (и связан), прежде чем его можно будет выполнить как часть программы.

1
29.06.2017, 06:07
4 ответа

Решение на вынос:

ls -pd !(*.jpg) | grep -Ev /$

Детали

Шаблон глобуса не опускается в подкаталоги -. lsделает :если вы передаете каталог в его командной строке, он отображает содержимое этого каталога.

Заменить lsнаecho:

$ echo !(*.jpg)

Или (почти )эквивалентное решение :говорит lsне спускаться в каталоги.

$ ls -d !(*.jpg)

Чтобы ответить на вопрос в комментариях :"как использовать команду ls для отображения только файлов, а не папок?" есть пара вариантов:

Краткий способ перечислить только каталоги:

echo */

Так что, возможно, ответ на список только файлов, а не каталогов может использоватьgrep -v

$ ls -p | grep -Ev /$

$ find. -maxdepth 1 ! -type d

Обратите внимание, что find будет перечислять точечные -файлы (скрытые файлы ). И find. -type dбудет (также )не переходить по символическим ссылкам.

Или прагматичный (posix )цикл:

$ for f in * ; do if [ -f "$f" ] ; then echo "$f" ; fi ; done

Конечно, конкретное решение для инвертированного расширения должно быть таким:

$ ls -pd !(*.jpg) | grep -Ev /$
11
111
112
1121
113
11a
11a1
1a1
1a2
1aa1.png
2a1
a.
a1a
a2a
aa
aa.gif
aa.png
aa.tiff
a.exe
a.gif
a.html
a.png
a.tiff
b2
b2a
ba.gif
ba.png
ba.tiff
b.html
cb1.png
d.gif

Примечание:

Опция -p вместе с grep позволяет идентифицировать каталоги,взгляните на справочную страницу ls:

-p, --file-type, --indicator-style=file-type

4
27.01.2020, 23:18

Должна ли оболочка быть bash? С установленными ZSH и EXTENDED_GLOBможно использовать (.), чтобы квалифицировать ()выражение glob как простые файлы.:

$ PS1='%% ' zsh -f
% setopt EXTENDED_GLOB
% mkdir foo && cd foo
% touch nope.jpg
% mkdir sub1
% touch asdf
% print ^*.jpg
asdf sub1
% print ^*.jpg(.)
asdf
% 
4
27.01.2020, 23:18

I can exclude using: GLOBIGNORE='sub1' before of ls, but what happens if I have more directories with differents names?

Из справочного руководства Bash , GLOBIGNORE — это:

A colon-separated list of patterns defining the set of filenames to be ignored by filename expansion. If a filename matched by a filename expansion pattern also matches one of the patterns in GLOBIGNORE, it is removed from the list of matches. The pattern matching honors the setting of the extglob shell option.

-1
27.01.2020, 23:18

Вы можете направить вывод lsв фильтр grep, например:

ls * | grep -v "jpg"

Чтобы вернуть все совпадения, не содержащие строку "jpg". (Флаг grep -vинвертирует совпадение, возвращая каждую строку, не содержащую указанную строку.)

-1
27.01.2020, 23:18

Теги

Похожие вопросы