Существует несколько проблем с Вашим кодом:
list=`ls dest_folder`
Вы храните вывод ls
без запаздывающих символов новых строк в $list
. ls
производит список имен файлов, разделенных с символами новой строки. newline
столь же допустимый символ как любой в имени файла, так, чтобы произведенный не мог использоваться надежно. Например, ls
вывод для каталога, который содержит a
и b
совпадает с тем для каталога, который содержит один названный файл a<newline>b
.
cd dest_folder
Вы не проверяете на отказ той команды. В целом необходимо проверить статус выхода команд, но это особенно верно для cd
, потому что остальная часть команд предполагает, что Вы находитесь в том новом каталоге, и это могло иметь поразительные последствия, когда Вы не.
cwd=`pwd`
Оболочки POSIX уже поддерживают (один) путь к текущему каталогу в $PWD
переменная, таким образом, Вы не должны должны быть использовать
здесь (особенно в общем случае, так как замена команды удалила бы запаздывание символов новой строки из пути). Кроме того, pwd
mv
принимает относительные пути, таким образом, Вы не должны создавать полный путь.
for folder in $list;do
Отъезд закрывшей кавычки переменной является split+glob оператором в оболочках. Таким образом, содержание переменной разделяется (на разделителях, упомянутых в $IFS
со специальными правилами для пробельных), и каждый элемент, получающийся из того разделения, ищется подстановочные символы, таким образом, они могут быть расширены до списка соответствия файлам.
Здесь, Вы действительно хотите разделение, но только на символах новой строки, и Вы не хотите globbing, таким образом, необходимо было бы отключить его:
IFS='
'; set -f
for folder in $list
mv ${cwd}/${folder}'/data/*' ${cwd}/${folder}
Снова, отъезд закрывшей кавычки переменной является split+glob оператором. Здесь, Вы не хотите ни одного, таким образом, необходимо заключить те переменные в кавычки.
Как уже упомянуто, подстановочные знаки только расширены при отсутствии заключения в кавычки Вам должен переместить это *
из кавычек. Если Вы отключили globbing ранее с set -f
, необходимо было бы восстановить его с set +f
до вызова той команды.
Намного лучший способ записать это был бы:
cd dest_folder &&
for folder in */;do
mv -- "${folder}data/"* "$folder"
done
Несколько примечаний, хотя:
data
папки.-i
опция к mv
).*/
, мы - цикличное выполнение по каталогам только, но это включает символьные ссылки на каталоги также. Если бы Вы быть бы, необходимо было бы добавить a [ -L "${folder%/}" ] && continue
в цикле.*/
расширится до себя, таким образом, Вы доберетесь и сообщение об ошибке от mv
высказывание его не может найти файл названным */data/*
. Точно так же, если не будет никакого нескрытого файла ни в одной из папок, то Вы получите сообщение об ошибке это that-folder/data/*
не существует.]Да, []sed[
] есть во всех версиях Unix. Это [] часть стандарта POSIX[]: каждый "официальный" Unix включает его, а также все дистрибутивы Linux и BSD.[
] Существует несколько различных версий команды []sed[
], с различными расширениями. Если Вы придерживаетесь общего подмножества опций []sed[
] и языка [], описанного POSIX[], то Ваша команда будет работать на всех системах.[
] POSIX не имеет мандата []sed -i [
], поскольку он является избыточным, а также не соответствует первоначальному назначению []sed[
]. Изначально []sed[
] предназначался для редактирования потоков []s[] (отсюда и его название []s[
]tream []ed[
]itor), а не для редактирования файлов. Правильным инструментом в POSIX для неактивного редактирования файлов является []ed[
][
printf "/text/d\nw" | ed file.txt
]
[]К сожалению, многие текущие системы считают []ed[
] устаревшим и не предоставляют его по умолчанию, даже если это предписывается POSIX.... Но, по крайней мере, она должна быть легко устанавливаемой на большинстве систем (в отличие от GNU sed, который может потребовать компиляции из исходного кода).[
][]EDIT:[] Также, вопреки формулировке вопроса, команда []d[
] из [](s)ed[
] делает больше, чем удаление данной строки, она удаляет любую строку, которая в ней содержится.[