2015-04-09 4 views
0

Я перебираю папку и в зависимости от длины файлов выполняю определенное условие. Кажется, я не согласен с этим. Я вычисляю и выводю длину строки в терминале.строка строки bash в цикле

echo $file|wc -c gives me the answer of all files in the terminal. 

Но включение этого в петлю невозможно

for file in `*.zip`; do 
    if [[ echo $file|wc -c ==9]]; then 
    some commands 

, где я хочу работать с файлами, которые имеют длину девять символов

+1

Вы понимаете, это цикл по всем файлам, которые заканчиваются с '.zip' в текущем каталоге? Если вы не добавили это расширение в текстовые файлы, это вряд ли сработает. –

+1

Он будет «работать», он просто будет сообщать «размер» zip-файла, который здесь может быть или не быть значимым. Также '* .zip' не хочет быть в обратном направлении. Это не исполняемая команда. –

+1

В этом фрагменте также есть несколько других проблем. Вам нужно пространство между '9' и']] ', пространство между' == 'и' 9', и вам нужно обернуть 'echo ' wc' в '$()' для его выполнения. Предоставив нам ошибки, которые вы получили из этого фрагмента и запустили его через shellcheck.net, помогли бы. –

ответ

2

Попробуйте это:

for file in *.zip ; do 
    wcout=$(wc -c "$file") 
    if [[ ${wcout%% *} -eq 9 ]] ; then 
    # some commands 
    fi 
done 

Оператор с переменным расширением %% удаляет все, что соответствует патту после него. Это шаблон глобуса, а не регулярное выражение.

Противоположный естественному хорошему пониманию типичных программистов оператор == в BASH сравнивает строки, а не цифры.

В качестве альтернативы (после комментария) Вы можете:

for file in *.zip ; do 
    wcout=$(wc -c < "$file") 
    if [[ ${wcout} -eq 9 ]] ; then 
    # some commands 
    fi 
done 

Дополнительное наблюдение состоит в том, что если BASH не может расширяться *.zip, как нет ZIP файлы в текущем каталоге будет проходить «* .zip» в $file и пусть одна итерация цикла. Это приводит к ошибке, сообщаемой командой wc. Поэтому было бы желательно добавить:

if [[ -e ${file} ]] ; then ... 

как механизм предупреждения.


Комментарии приводят к другой форме этого раствора (плюс я добавил мою безопасность механизма):

for file in *.zip ; do 
    if [[ -e "$file" && (($(wc -c < "$file") == 9)) ]] ; then 
    # some commands 
    fi 
done 
+3

Используйте' wc -c <файл', чтобы просто получить значение. – fedorqui

+0

В этом случае 'wc -c <$ file'. –

+3

Красиво сделано; если вы прислушаетесь к советам @ fedorqui, вы можете упростить 'if (($ (wc -c <" $ file ") == 9)); then' (используя оценку _arithmetic_ позволяет использовать обычные операторы); для надежности, пожалуйста, дважды укажите «$ file». – mklement0

0

с использованием фильтра вне цикла

ls -1 *.zip \ 
| grep -E '^.{9}$' \ 
| while read FileName 
    do 
     # Your action 
    done 

с использованием фильтра внутри контура

ls -1 *.zip \ 
| while read FileName 
    do 
     if [ ${#FileName} -eq 9 ] 
     then 
     # Your action 
     fi 
    done 

альтернативы ls -1, что всегда немного dangereous, find . -name '*.zip' -print [но вы NEET добавить 2 длины обугленной или фильтровать формы имени headin ./ и, возможно, ограничить текущую глубину папки]

+2

Справочная информация о том, почему вывод 'ls' синтаксического анализа не является хорошей идеей: http://mywiki.wooledge.org/ParsingLs. Ваша команда 'find' будет искать всю _subtree_. С простым шаблоном, например '* .zip', с использованием простого расширения пути оболочки (globbing) -' for f in * .zip; do ... '- проще, надежнее и эффективнее. 'в то время как IFS = read -r FileName' сделает ваш цикл более надежным. – mklement0

+1

согласен, ядро ​​не было ls/find, но цикл и фильтр – NeronLeVelu