Не одна линия, но избегает sed
и должен работать так же хорошо, если вы собираетесь использовать его для сценария в любом случае. (Заменить mv
с echo
, если вы хотите проверить)
В Баш 4+
#!/bin/bash
shopt -s globstar
for file in **/*; do
filename="${file##*/}"
if [[ -f $file && $filename == *" "* ]]; then
onespace=$(echo $filename)
dir="${file%/*}"
[[ ! -f "$dir/${onespace// /-}" ]] && mv "$file" "$dir/${onespace// /-}" || echo "$dir/${onespace// /-} already exists, so not moving $file" 1>&2
fi
done
Старые Баш
#!/bin/bash
find . -type f -print0 | while read -r -d '' file; do
filename="${file##*/}"
if [[ -f $file && $filename == *" "* ]]; then
onespace=$(echo $filename)
dir="${file%/*}"
[[ ! -f "$dir/${onespace// /-}" ]] && mv "$file" "$dir/${onespace// /-}" || echo "$dir/${onespace// /-} already exists, so not moving $file" 1>&2
fi
done
Объяснение алгоритма
**/*
Это рекурсивен список всех файлов в текущем каталоге (**
технически это делает, но /*
добавляется в конце, так что не отображает сам каталог)
${file##*/}
будет искать самые длинные картины */
в файле и удалите его из строки. например /foo/bar/test.txt
печатаются в test.txt
$(echo $filename)
Без процитировать эхо будет усечение пространства к одному, что делает их легче заменить одним -
для любого количества пробелов
${file%/*}
Удалить все после того, как и в том числе последнего /
, например,/foo/bar/test.txt
печатает /foo/bar
mv "$file" ${onespace// /-}
заменить каждый пробел в нашем имени файла с -
(мы проверяем, если hyphened версия существует, прежде чем руки, и если он делает эхо, что он не в стандартный вывод, отметить &&
обрабатывается до ||
в Баш)
find . -type f -print0 | while read -r -d '' file
Этом используется, чтобы избежать разбивать строки с пробелами в них, установив ограничитель и не обрабатывает \
Пример вывода
$ tree
.
├── bar
│ ├── some dir
│ │ ├── some-name-without-space1.pdf
│ │ ├── some name with space1.pdf
│ ├── some-name-without-space1.pdf
│ ├── some name with space1.pdf
│ └── some-name-with-space1.pdf
└── space.sh
$ ./space.sh
bar/some-name-with-space1.pdf already exists, so not moving bar/some name with space1.pdf
$ tree
.
├── bar
│ ├── some dir
│ │ ├── some-name-without-space1.pdf
│ │ ├── some-name-with-space1.pdf
│ ├── some-name-without-space1.pdf
│ ├── some name with space1.pdf
│ └── some-name-with-space1.pdf
└── space.sh
почти наверняка процитировать проблема, но я не уверен, если процитировать '{}' необходимо или поможет. Стоит попробовать, верно? Еще, вернитесь к вашему решению цикла и dbl-quote все ссылки на переменные. Удачи. – shellter