Ответ 1
Используйте basename
и dirname
, что вам нужно.
part1=`dirname "$p"`
part2=`basename "$p"`
У меня есть файл (например, называемый list.txt
), который содержит относительные пути к файлам, по одному пути в строке, т.е. что-то вроде этого:
foo/bar/file1
foo/bar/baz/file2
goo/file3
Мне нужно написать bash script, который обрабатывает один путь за раз, разбивает его на последнюю косую черту, а затем запускает другой процесс, передавая ему две части пути в качестве аргументов. Пока у меня есть только часть цикла:
for p in `cat list.txt`
do
# split $p like "foo/bar/file1" into "foo/bar/" as part1 and "file1" as part2
inner_process.sh $part1 $part2
done
Как мне разделить? Будет ли это работать в вырожденном случае, когда путь не имеет косой черты?
спасибо
Используйте basename
и dirname
, что вам нужно.
part1=`dirname "$p"`
part2=`basename "$p"`
Собственный 100% bash способ и безопасен в отношении имен файлов, содержащих пробелы или забавные символы (при условии, что inner_process.sh
обрабатывает их правильно, но это другая история):
while read -r p; do
[[ "$p" == */* ]] || p="./$p"
inner_process.sh "${p%/*}" "${p##*/}"
done < list.txt
и для каждого файла это не fork dirname
и basename
(в подоболочках).
Строка [[ "$p" == */* ]] || p="./$p"
здесь на всякий случай $p
не содержит никакой косой черты, затем она добавляет к ней ./
.
См. раздел Расширение параметров оболочки в Bash Справочное руководство для получения дополнительной информации о символах %
и ##
.
Чтобы ответить на критику @gniourf_gniourf ответа @piokuc, сохраняя его коротким и простым (если не так эффективно):
part1=`dirname "$p"`
part2=`basename "$p"`
(Я бы ответил в комментарии, но это синтаксически невозможно.)
Вот один пример, чтобы найти и заменить расширения файлов на xml.
for files in $(ls); do
filelist=$(echo $files |cut -f 1 -d ".");
mv $files $filelist.xml;
done