2015-08-30 1 views
1

Прежде всего, привет всем, это мой первый пост здесь. Клянусь, я проверил сайт на подобные вопросы, чтобы избежать проблемы с «двойным сообщением о том же аргументе», но никто из них не ответил точно на мой вопрос. Проблема в том, что в приведенном ниже коде я всегда получаю сообщение "There are no files with this extension", когда я вызываю скрипт, передающий ему расширение как первый аргумент.Как передать список файлов с определенным расширением в цикле for в bash

#!/bin/bash 
if [ "$1" ]; 
    then 
     file=*."$1"; 
     if [ -f "$file" ]; 
      then 
       for i in "$file"; 
       [...do something with the each file using "$i" like echo "$i"] 
      else 
       echo "There are no files with this extension"; 
     fi; 
    else 
     echo "You have to pass an extension" 
    fi; 

Я попытался использовать двойную скобку, используя и не используя кавычки в вложенном, если, используя *."$1" непосредственно в случае, но ни одно из этого решения не работал.

ответ

1

Одна из проблем заключается в том, что вы не цитируя переменную, когда вы впервые назначили значение file. В этом заявлении:

file=*."$1"; 

* будет интерпретатором, так, например, если вы прошли в .py в командной строке, файл может в конечном итоге со значением file1.py file2.py, который отбросит тест существование файла позже.

Другая проблема, как указывает @sideshowbarker, заключается в том, что вы не можете использовать подстановочные знаки с помощью [ -f ... ].

Другая переменная со ссылкой на вопрос, что цитирование ингибирует расширение подстановочных, таким образом, что даже без теста на существование файла, если $file является, например, *.txt, то это:

for x in "$file"; do ... 

переберёт одного аргумента с буквальное значение *.txt, в то время как это:

for x in $file; do ... 

переберёт все файлы, которые заканчиваются с .txt расширением (если нет ни одного, в этом случае она будет цикл раз Wi й $x установлен в литеральное значение *.txt).

Как правило, вы должны написать свой скрипт, чтобы ожидать список аргументов, и разрешить пользователю называть его как myscript *.txt ... то есть оставить обработку подстановочных знаков интерактивной оболочке и просто позволить вашему скрипту обрабатывать список аргументы. Тогда это становится просто:

for i in "[email protected]"; do 
    echo do something with this file named "$x" 
done 

Если вы действительно хотите, чтобы справиться с подстановочным расширением в сценарии, что-то подобное может работать:

#!/bin/bash 
if [ "$1" ]; 
    then 
     ext="$1" 
     for file in *.$ext; do 
      [ -f "$file" ] || continue 
      echo $file 
     done 
    else 
     echo "You have to pass an extension" 
    fi; 

Заявление [ -f "$file" ] || continue необходимо там из-за дела я упомянул ранее: если файлов нет, цикл будет выполняться один раз с расширением буква *.$ext.

+0

Вы были действительно исчерпывающими, спасибо большое! –

+0

Еще один вопрос, в этом случае, где я могу поместить «echo». Не было файла с этим расширением?? Я попытался разместить его после 'done', но похоже на' [-f "$ file"] || continue' заставляет скрипты останавливаться вообще, если он не находит никакого файла, который соответствует. –

+0

Как сценарий написан в моем примере, вы не можете легко предоставить эту ошибку. Вы могли бы поддерживать количество совпадающих файлов в 'for 'loop и проверить, будет ли это число' 0'. – larsks

Смежные вопросы