Я використовую наступний код для налаштуваннязмінна, що містить ряд різних імен файлів, після чого я згодом виконуватиму деякі функції. Задіяні файли знаходяться в іншому каталозі (DIRECTORY
) в каталог, де виконується код (CURRENT_DIRECTORY
). Я думав, що наступний код може бути використаний для переходу в каталог, що містить файли cd $DIRECTORY
, збережіть список файлів у змінній $FILES
а потім поверніться до початкового каталогу (cd $CURRENT_DIRECTORY
), де решта коду може бути виконана. Однак якщо я виконую дві команди ехо, перша містить список файлів, коли я перебуваю в каталозі, де зберігаються файли, але друга команда echo просто друкує "vclist_2d_*.txt"
, тобто він інтерпретує це як рядок, а не список файлів (імовірно, тому, що я змінився в початковий каталог, і тому він не може знайти жодні файли, які відповідають vclist_2d_*.txt
). Чому це відбувається, і як я можу обійти цю проблему (не запускаючи все в одному каталозі)?
#!/bin/bash
CURRENT_DIRECTORY=`pwd`
DIRECTORY=/home/Documents/NewDirectory/
cd $DIRECTORY
pwd
FILES=vclist_2d_*.txt
echo $FILES
cd $CURRENT_DIRECTORY
echo $FILES
Відповіді:
4 для відповіді № 1Вам потрібно зберегти результат глобального розширення.
Глобуси не розширюються простими змінними завданнями, тому ваш поточний код розширює глобус, коли ви echo
це (саме тому ви отримуєте поведінку, яку бачите). Спробуйте echo "$FILES"
і це, наприклад, взагалі не виграє.
Однак призначення масивів не розширюється FILES=(vclist_2d_*.txt)
розгорнуть глобус негайно, а потім за допомогою echo "${FILES[@]}"
пізніше буде працювати правильно.
1 для відповіді № 2
FILES=vclist_2d_*.txt
не розширюється оболонкою. FILES
тепер містить рядок vclist_2d_*.txt
.
echo $FILES
посилає echo vclist_2d_*.txt
до оболонки. Потім оболонка розширює візерунок, в результаті чого виникає або A) рядок vclist_2d_*.txt
якщо шаблон нічого не відповідає, або B) список назв відповідних файлів.
Потім ви змінюєте каталог і повторюєте процес. У жодному разі немає списку файлів, присвоєних будь-якій змінній.
Тепер ти міг призначити вихід від echo vclist_2d_*.txt
до змінної (SOMEVAR=$(echo vclist_2d_*.txt)
, але це вирішило б вашу проблему лише на півдорозі. Як ви маєте намір "діяти на кожен файл у списку"? Якщо ви думаєте про а for file in $SOMEVAR
, подумайте, що буде, якщо ім'я файлу містить пробіл ...
Найпростіше, найбільш надійне рішення для цього - використовувати find
замість цього:
find $DIRECTORY -name "vclist_2d_*.txt" -exec do_something {} +
Це призводить до do_something
передав список відповідних файлів. Якщо список є дуже довго, він може бути розділений на кілька дзвінків do_something
.
find $DIRECTORY -name "vclist_2d_*.txt" -exec do_something {} ;
Це призводить до do_something
викликається для кожного відповідного файлу.
Якщо є шанс, що ваш струм каталог може містити файли, що відповідають шаблону, переданому до find
вище, вам потрібно уникнути зірочки (додавши лапки, як я, або уникнути її через *
), щоб уникнути розширення оболонки find
командувати в щось інше.