Цикл по именам файлов без eval

В справочной странице говорится:

--disable device  
    Disable the device. This call is equivalent to 
    xinput --set-prop device "Device Enabled" 0

Таким образом, вы можете использовать xinput --list-propsи grep, чтобы узнать, включено устройство или нет.

-3
24.02.2019, 06:14
2 ответа

Использованиеfind:

find /media/mybook/Example*/ -type f -name '*.mkv' -print

Добавьте -maxdepth 1перед -type f, если вы не хотите рекурсивно обращаться к подкаталогам.

Или просто прямой цикл оболочки (не будет работать, если есть много тысяч файлов )и предполагается, что вы хотите просмотреть только первый уровень подкаталога:

for pathname in /media/mybook/Example*/*.mkv; do
    printf '%s\n' "$pathname"
done

Если вы хотите рекурсивно перейти в подкаталоги, используя zshили bashс параметром оболочки globstar, установленным (, снова не будет работать для нескольких тысяч файлов):

for pathname in /media/mybook/Example*/**/*.mkv; do
    printf '%s\n' "$pathname"
done

Связанные:


Чтобы сделать что-нибудь с путями:

Сfind:

find /media/mybook/Example*/ -type f -name '*.mkv' -exec sh -c '
    for pathname do
        # Use "$pathname" here
    done' sh {} +

... где sh -c, очевидно, можно было бы изменить на bash -cили zsh -c, если вам нужно использовать какие-либо специальные функции этих оболочек.

Связанные:

С петлей-раковиной:

for pathname in /media/mybook/Example*/*.mkv; do
    # Use "$pathname" here
done

Также связанные:

0
28.01.2020, 05:19

Я не понимаю, зачем здесь использовать eval. Вы можете просто написать s=$(ls "$i"*.mkv). Но вызов lsбессмысленен и исказит имена файлов . Просто перебирайте файлы в обычном режиме.

for dir in /media/mybook/Example*/; do;
  if ! [ -d "$dir" ]; then continue; fi
  for file in "$dir"/*.mkv; do
    if ! [ -e "$file" ]; then continue; fi
    echo "$file"
  done
done

Обратите внимание, что "$dir"находится в двойных кавычках (, поэтому любые специальные символы, такие как пробелы в имени каталога, остаются такими, как они есть ), но *находится вне кавычек, поэтому он рассматривается как подстановочный знак..

Строки с continueпредназначены для пропуска особого случая, когда подстановочный знак ничему не соответствует. В sh, когда подстановочный знак не совпадает, он остается как есть, и поэтому forвидит список имен с одним элементом, который буквально/media/mybook/Example*/(для внешнего цикла ). В некоторых оболочках (ksh, bash, zsh )есть способ избежать этого, например в bash:

shopt -s nullglob
for dir in /media/mybook/Example*/; do;
  for file in "$dir"/*.mkv; do
    echo "$file"
  done
done

Если вы просто обрабатываете файлы и вам не нужно ничего делать с каталогами, нет смысла иметь два вложенных цикла.

for dir in /media/mybook/Example*/*.mkv; do
  if ! [ -e "$file" ]; then continue; fi
  echo "$file"
done

Все эти фрагменты действуют на файлы внутри самих Example*каталогов, а не в их подкаталогах. Если вы хотите рекурсивно перемещаться по каталогам, см. ответ Кусалананды .

1
28.01.2020, 05:19

Теги

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