Найти конкретный файл в ближайшем предке текущего рабочего каталога

Из man pwd на моем Ubuntu:

ваша оболочка может иметь свою собственную версию pwd

Я использую bash. Простая команда pwd дает мне путь относительно символической ссылки; однако /bin/pwd возвращает фактический путь. Команда cd также является встроенной командой bash.

Другими словами: это специфично для shell.

EDIT: комментарий thrig'а (см. ниже) кажется лучшей альтернативой всему, что я написал ниже этой строки.

Для "резервного копирования" в фактический каталог попробуйте cd "$(/bin/pwd)/..." или cd "$(/bin/pwd)"; cd .... Вторая форма может быть настроена для создания псевдонима cd, я думаю:

alias cd='cd "$(/bin/pwd)"; cd'

Подобным образом можно избавиться от встроенного в bash pwd:

alias pwd=`/bin/pwd`
3
02.07.2016, 16:04
3 ответа

Это прямой перевод алгоритма find-config в общих командах оболочки (проверенных в bash, ksh и zsh), где я использую код возврата 0 для обозначения успеха и 1 для обозначения NULL / сбой.

findconfig() {
  # from: https://www.npmjs.com/package/find-config#algorithm
  # 1. If X/file.ext exists and is a regular file, return it. STOP
  # 2. If X has a parent directory, change X to parent. GO TO 1
  # 3. Return NULL.

  if [ -f "$1" ]; then
    printf '%s\n' "${PWD%/}/$1"
  elif [ "$PWD" = / ]; then
    false
  else
    # a subshell so that we don't affect the caller's $PWD
    (cd .. && findconfig "$1")
  fi
}

Пример выполнения с украденной установкой , скопированной и расширенной из ответа Стивена Харриса :

$ mkdir -p ~/tmp/iconoclast
$ cd ~/tmp/iconoclast
$ mkdir -p A/B/C/D/E/F A/good/show 
$ touch A/good/show/this A/B/C/D/E/F/srchup A/B/C/thefile 
$ cd A/B/C/D/E/F
$ findconfig thefile
/home/jeff/tmp/iconoclast/A/B/C/thefile
$ echo "$?"
0
$ findconfig foobar
$ echo "$?"
1
5
27.01.2020, 21:09

Один из способов сделать это:

#! /bin/sh
dir=$(pwd -P)
while [ -n "$dir" -a ! -f "$dir/$1" ]; do
    dir=${dir%/*}
done
if [ -f "$dir/$1" ]; then printf '%s\n' "$dir/$1"; fi

Замените pwd -P на pwd -L , если вы хотите следовать символическим ссылкам вместо проверки физических каталогов.

4
27.01.2020, 21:09

Простой цикл проверки текущего каталога, и если он не найден, то отключение последнего компонента будет работать

#!/bin/bash

wantfile="$1"

dir=$(realpath .)

found=""

while [ -z "$found" -a -n "$dir" ]
do
  if [ -e "$dir/$wantfile" ]
  then
    found="$dir/$wantfile"
  fi
  dir=${dir%/*}
done

if [ -z "$found" ]
then
  echo Can not find: $wantfile
else
  echo Found: $found
fi

Например, если это дерево каталогов:

$ find /tmp/A
/tmp/A
/tmp/A/good
/tmp/A/good/show
/tmp/A/good/show/this
/tmp/A/B
/tmp/A/B/C
/tmp/A/B/C/thefile
/tmp/A/B/C/D
/tmp/A/B/C/D/E
/tmp/A/B/C/D/E/F
/tmp/A/B/C/D/E/F/srchup

$ pwd      
/tmp/A/B/C/D/E/F

$ ./srchup thefile
Found: /tmp/A/B/C/thefile

Мы видим, что поиск шел вверх по дереву, пока не нашел то, что искали.

3
27.01.2020, 21:09

Теги

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