'Sed' существует всего *, отклоняет?

Существует несколько проблем с Вашим кодом:

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/* не существует.
5
19.07.2014, 01:17
2 ответа
[

]Да, []sed[] есть во всех версиях Unix. Это [] часть стандарта POSIX[]: каждый "официальный" Unix включает его, а также все дистрибутивы Linux и BSD.[

] [

] Существует несколько различных версий команды []sed[], с различными расширениями. Если Вы придерживаетесь общего подмножества опций []sed[] и языка [], описанного POSIX[], то Ваша команда будет работать на всех системах.[

].
9
27.01.2020, 20:32
[

] 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[] делает больше, чем удаление данной строки, она удаляет любую строку, которая в ней содержится.[

].
6
27.01.2020, 20:32

Теги

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