У меня есть список каталогов

/u2/tip/coy/inter/fcs/
/u2/tip/coy/inter/fcs/devel
/u2/tip/coy/inter/fcs/ecom_flink
/u2/tip/coy/inter/fcs/totalstable
/u2/tip/coy/inter/fcs/develbi
/u2/tip/coy/inter/fcs/tgn
/u2/tip/coy/inter/fcs/tdhmdcuat
/u2/tip/coy/inter/fcs/ecom_tdhmdc
/u2/tip/coy/inter/fcs/ecom_tdh
/u2/tip/coy/inter/fcs/grow
/u2/tip/coy/inter/fcs/sgsb
/u2/tip/coy/inter/fcs/tdhmdc
/u2/tip/coy/inter/fcs/ecom_grow
/u2/tip/coy/inter/fcs/masupport
/u2/tip/coy/inter/fcs/totalslow
/u2/tip/coy/inter/fcs/ecom_sgsb
/u2/tip/coy/inter/fcs/tdh

Но только часть из них содержит каталог */out:

/u2/tip/coy/inter/fcs/devel/out
/u2/tip/coy/inter/fcs/ecom_flink/out
/u2/tip/coy/inter/fcs/ecom_grow/out
/u2/tip/coy/inter/fcs/ecom_sgsb/out
/u2/tip/coy/inter/fcs/ecom_tdhmdc/out
/u2/tip/coy/inter/fcs/ecom_tdh/out
/u2/tip/coy/inter/fcs/tdhmdc/out
/u2/tip/coy/inter/fcs/tdh/out

Мне было интересно, есть ли способ использовать команду (например, find), которая, учитывая /u2/tip/coy/inter/fcs , вернет этот список:

devel
ecom_flink
ecom_grow
ecom_sgsb
ecom_tdhmdc
ecom_tdh
tdhmdc
tdh

Без помощи grep или grep подобных фильтров / инструментов (sed , awk и друзья)

2 ответа2

3
find /u2/tip/coy/inter/fcs -type d -name "out"

возвращает подмножество папок,

/u2/tip/coy/inter/fcs/devel/out
/u2/tip/coy/inter/fcs/ecom_flink/out
/u2/tip/coy/inter/fcs/ecom_grow/out
…etc 

Затем вы можете запустить dirname для этих результатов:

find /u2/tip/coy/inter/fcs -type d -name "out" -exec dirname {} \;

/u2/tip/coy/inter/fcs/devel
/u2/tip/coy/inter/fcs/ecom_flink
/u2/tip/coy/inter/fcs/ecom_grow
…etc

И с помощью sh -c вы можете выполнить basename для этого результата:

find /u2/tip/coy/inter/fcs -type d -name "out" -exec sh -c 'basename "$(dirname "$0")"' {} \;

спасибо Slhck за вышеизложенное.

Вопрос в следующем: проще ли, быстрее или лучше запустить оболочку, содержащую процесс, который работает с выходом подоболочки, содержащей другой процесс, чем передать вывод find в sed/awk?

0
find /u2/tip/coy/inter/fcs -name 'out' -type d |
while read line ; do
    IFS='/'
    set -- $line
    num=$(( $# - 1))
    eval  "echo \"\${$num}\""
done

но это с треском провалится, когда в имени файла есть новые строки

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