Замените имена каталогов в пути в сценарии ksh - PullRequest
1 голос
/ 06 мая 2019

Я хочу создать относительный путь из заданного абсолютного пути и сохранить его в переменной.

/aaa/bbb/ccc/ddd/eee.txt должен производить ../../../.., который я могу добавить к другому пути согласно требованию.

$filepath=/aaa/bbb/ccc/ddd/eee.txt

Я хочу создать новую переменную с именем $abs, которая должна содержать ../../../...

Попробовал это:

echo "$filepath" | sed -r 's/*/../g'

Вышеупомянутый шаблон не работает согласно требованию.

Будучи новичком, я мог бы задавать глупые вопросы.

Прошу прощения и заранее спасибо!

Ответы [ 2 ]

1 голос
/ 07 мая 2019

Вы можете избежать косой черты с помощью другого символа, например #.
Сначала вы обрезаете имя файла по пути с помощью «$ {filepath% / *}» (лучше, чем basename).
Вы заменяете каждую строку по крайней мере одним символом точками.
И наконец удалите начальный слеш.

echo "${filepath%/*}"| sed 's#[^/]\+#...#g;s#\/##'
1 голос
/ 07 мая 2019

Я не уверен, что sed способен на это, но может показать команду awk, которая это делает.

echo "$filepath" | awk -F'/' '{ for ( i = 2; i < NF-1; i++ ) printf "../" } END{print ".."}'

, где -F '/' - разделитель полей разделить текст /aaa/bbb/ccc/ddd/eee.txt на 6 разделов, каждый раздел может использоваться как переменная в awk, это также приводит к удалению разделителя полей / в данном случае из текста.

  • $1 является '' пустым как первое / не иметь ничего перед ним.
  • $2 является aaa
  • $3 - это bbb
  • $4 is ccc
  • $5 is ddd
  • $6 - это eee.txt

NF переменная содержит сколько у нас полей.


for ( i = 2; i < NF-1; i++ ) для цикла

Я начинаю с 2 вместо 1, так как первое поле всегда пусто, потому что абсолютный путь всегда начинается с /, это поле будет игнорироваться.

Я также вычту переменную NF с последним полем 1, которое будет содержать имя файла, следовательно, оно не является каталогом, однако это позволяет решить проблему, если это каталог, а / нет в конце, например, /home/jondoe вы получите .. вместо ../.., тогда как /home/jondoe/ будет работать.

printf "../" печатаются рядом друг с другом в каждом цикле, пока идет цикл.

END{print ".."} напечатает .. независимо от того, что произошло, является вводом. Это приведет к .. в конце текста, в то время как для цикла напечатайте ../ несколько раз


Эта команда все еще может быть улучшена для устранения ловушек, подобных той, что я упоминал Я надеюсь, что это соответствует вашим потребностям.

...