Подтвердить что ты не робот

Ubuntu bash script: как разбить путь по последней косой чертой?

У меня есть файл (например, называемый 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

Как мне разделить? Будет ли это работать в вырожденном случае, когда путь не имеет косой черты?

спасибо

4b9b3361

Ответ 1

Используйте basename и dirname, что вам нужно.

part1=`dirname "$p"`
part2=`basename "$p"`

Ответ 2

Собственный 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 Справочное руководство для получения дополнительной информации о символах % и ##.

Ответ 3

Чтобы ответить на критику @gniourf_gniourf ответа @piokuc, сохраняя его коротким и простым (если не так эффективно):

part1=`dirname "$p"`
part2=`basename "$p"`

(Я бы ответил в комментарии, но это синтаксически невозможно.)

Ответ 4

Вот один пример, чтобы найти и заменить расширения файлов на xml.

for files in $(ls); do

    filelist=$(echo $files |cut -f 1 -d ".");
    mv $files $filelist.xml;
done