Как заставить оболочку распознавать имена файлов, возвращаемые командой `ls -A`, и эти имена содержат пробелы?

Я думаю, что вы как-то удалили ubuntu-desktop. Попробуйте переустановить ubuntu-desktop, введя: sudo apt-get install ubuntu-desktop в терминал.

1
задан 1 May 2014 в 22:44

4 ответа

for повторяет слова, слова разделяются пробелами. Вы не должны перебирать вывод ls, вы должны использовать * .*:

for file in * .* ; do
    if [[ $file = . || $file = .. ]] ; then
        continue
    fi
    # ...
done
9
ответ дан 24 May 2018 в 10:48

Вы можете включить скрытые файлы («точечные файлы») в оболочку оболочки bash '*', установив параметр оболочки dotglob

shopt -s dotglob
for file in *
do 
  echo "$file"
done

, например. для каталога, содержащего file, file with spaces и .hidden file (последний из которых скрыт и имеет пробел), это создает

file
file with spaces
.hidden file

Возможно, вы захотите добавить опцию nullglob а также для предотвращения ошибки в случае, когда каталог пуст - см. отличный BashFAQ / 004. Не забудьте указать переменную "$file", а также лучше не использовать все шапки для ваших имен переменных.

6
ответ дан 24 May 2018 в 10:48
  • 1
    Это сработало, но это смешно. В руководстве для команды shopt нет страниц. – Patterson 14 March 2014 в 19:39
  • 2
    Это встроенная оболочка bash - вы можете получить основную помощь, набрав help shopt в приглашении bash и список доступных параметров и их статус, набрав shopt без каких-либо аргументов. Для получения более полной информации вы можете проверить справочную страницу bash (введите /shopt изнутри человека, чтобы найти раздел магазина). – steeldriver 14 March 2014 в 19:48
  • 3
    Понял! Вы являетесь мастерами в сценарии оболочки. Нет лучшего форума! – Patterson 14 March 2014 в 19:54

Если вы еще не поняли, разбор ls - это плохая идея. Если вы не можете знать, что имена ваших файлов всегда будут нормальными (вы, как правило, не можете), вам нужно иметь дело с именами файлов, содержащими:

пробелы и вкладки последовательных пробелов или строк новых строк () возврат каретки (\r) обратная косая черта (\)

Все вышеперечисленное разрешено ядром Linux (и, как гарантируется, сбой вашего sysadmin mad). Следующие два метода могут иметь дело с любой комбинацией вышеуказанного. Я использую cp file directory/ в качестве примера команды):

Используйте find и его -exec вариант, {} будет заменен каждым найденным файлом или каталогом.
find . -exec cp {} directory/
Результаты поиска трубы в xargs в виде нулевых разделенных строк (-print0), скажите xargs, чтобы прочитать нулевой раздел (-0) и сообщить ему заменить {} на каждое имя файла / каталога (-I {} ]).
find . -print0 | xargs -0 -I {} cp {} directory/
Используйте только оболочку, чтобы также совместить dotfiles, активируйте dotglob
 shopt -s dotglob
 for i in *; do cp -v "$i" directory/; done
Объедините мощность find и универсальность оболочки
find . -print0 | while IFS= read -r -d '' i; do cp "$i" directory/; done
. IFS= отключает разделение в пробелах, -r отключает обратную косую черту (позволяет обратную косую черту обрабатывать буквально), -d '' устанавливает разделитель записи (строки, если хотите) в значение null.
1
ответ дан 24 May 2018 в 10:48

Как насчет:

ls -A | while read fname
do
    echo "$fname" # your code goes here
done

Piping ls заставляет его отправлять 1 имя файла в строке, read затем принимает строку в переменную fname.

0
ответ дан 24 May 2018 в 10:48

Другие вопросы по тегам:

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