-1

Эта команда:

find ./ -name "mybinaryrpm-1.0.24-1.1.i586.rpm"

дает вывод:

./DirectoryName/SubDirectory/mybinaryrpm-1.0.24-1.1.i586.rpm

но я хочу только вывод:

mybinaryrpm-1.0.24-1.1.i586.rpm

Как я могу получить это?


Что я действительно пытаюсь сделать:

  1. Прочитайте входной файл, который содержит список двоичных имен файлов, разделенных строкой
  2. Поиск файлов с соответствующими именами в текущем каталоге рекурсивно
  3. Если найдено более одного совпадения, рассмотрите только один результат поиска и скопируйте файл в соответствующий каталог назначения.

Текущий код:

while read line; do
    binaryRpm=$(find ./ -name "$line" -exec basename {} \;)
    echo " [ Read From File: $line ] <==> [ Find Command Searched: $binaryRpm ]"
    ## If found then copy the binary file to dest dir
    ## TODO: If Find Command finds more than One File with the
    ## Same Name, then ONLY ONE FILE MUST be Compared and copied to
    ## the Release Directory
    if [ "$line" != "$binaryRpm" ]; then
        echo "---------- Binary File Searching---------- "
        continue
    else
        echo " !!!!!! Binary File Found ==> $binaryRpm !!!!!! "
    fi
done < "$FILENAME"

3 ответа3

2

Что ж, ваш пример на самом деле не имеет смысла, так как вы, как отмечено в комментарии, хотите получить тот же вывод, что и в качестве ввода. Если вы знаете вход, вы уже знаете выход.

Но, в общем, используйте функцию find 's -printf :

find . -name "mybinaryrpm-1.0.24-1.1.i586.rpm" -printf '%f\n'

От man find , раздел -printf:

%f    File's name with any leading directories removed (only the last element).

Это доступно только для поиска GNU, но инструменты GNU - это стандарт Linux, который вы запрашивали. Он также может быть установлен на более или менее каждой соответствующей платформе.


Пример минимального кода, который делает то, что вы действительно пытаетесь сделать:

#!/bin/sh
FILENAME="/path/to/file/with/filenames"

while read line; do
    binaryRpm=$(find -name "${line}" -type f | head -1)
    if [ -z "${binaryRpm}" ]; then
        echo "No matches found for \"${line}\"."
    else
        echo "Match for \"${line}\" found at \"${binaryRpm}\""
    fi
done < "${FILENAME}"

Комментарии к моему примеру выше:

  • head -1 будет держать только первый матч.
  • [ -z ] проверяет, является ли переменная пустой (она будет пустой, если find не найдет ничего выше).

Комментарии к вашему сценарию:

  • Вам не нужно проверять, совпадает ли имя файла со строкой, так как find возвращает только те, которые совпадают. Я предполагаю, что вы используете его, чтобы отменить несколько матчей, но head - лучший инструмент для этого.
  • Вам не нужен оператор continue том виде, в каком он есть, так как скрипт выпрыгнет из предложения if и в любом случае выполнит цикл for непосредственно после него.
0

Попробуйте эту команду:

find . -name "mybinaryrpm-1.0.24-1.1.i586.rpm" -exec basename {} \;
0

Чтобы ответить на ваш вопрос, вы можете попробовать что-то вроде этого:

find ./ -name "mybinaryrpm-1.0.24-1.1.i586.rpm" | sed 's|^\..*/\(.*\)|\1|g'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .