bash仅将最高(明智的是文件夹层次结构)位置结果存入变量

时间:2019-01-14 07:09:54

标签: bash shell

我正在尝试使用bash仅将最高(在文件夹层次结构上)位置结果放入变量中。

administrator@JenkisSrv01:/tmp/test/frontend-2.0$ find -name pom.xml
./server/pom.xml
./server/mock/pom.xml
./assembly/pom.xml
./pom.xml

我只希望将pom.xml的父文件夹的位置插入变量中。

LOCATION =。/ 或绝对路径也可以使用“ pwd”工作。 LOCATION = / tmp / test / frontend-2.0

我想不出一个很好的命令来将此信息转换为变量... 有人吗?

4 个答案:

答案 0 :(得分:1)

要仅获取目录名称,可以使用以下命令

find $(pwd) -name pom.xml -exec dirname {} \;

如果只想获得最短路径,则可以运行以下命令:

find $(pwd) -name pom.xml -exec dirname {} \; | awk '{ print length($0) " " $0; }' | sort -r -n|cut -d ' ' -f 2-|tail -1

答案 1 :(得分:1)

这将收集斜杠数量最少的路径,并将其打印出来以替换为命令。

location=$(find . -name pom.xml -exec dirname {} \; |
    awk -F / 'NR==1 || NF < min { min=NF; i=0 }
        NF<=min { a[++i] = $0 }
        END { for(j=1; j<=i; ++j) print a[j] }')

NF是字段数(因此,由于-F /也是斜杠数加一),而NR是当前行号。因此,将具有最小斜杠数量的路径收集到数组a中,如果我们看到一个新的最小数量,请重新开始。 (为了避免重复,在脚本中将这些条件的顺序颠倒了。)最后,打印累积的路径名数组。

如果您的文件名不完全规则,则可能将它们收集到Bash数组中而不是字符串中。

不要对您的私有变量使用大写;大写变量保留供系统使用。

答案 2 :(得分:1)

假设文件名中不包含转义符(\ 0x1b),怎么办:

esc=$'\e'
while read -r -d "" f; do
    printf "%s%c" "${f//[^\/]/}$esc$f" $'\0'
done < <(find . -name pom.xml -print0) | sort -t "$esc" -z -k 1 | head -1 -z | cut -d "$esc" -z -f 2

产量:

./pom.xml

首先,它从文件名中提取斜杠,将斜杠附加到原始文件名,并使用转义符作为分隔符,然后对文件名进行排序,标头和剪切。斜杠计数用于排序斜杠最少的文件。

答案 3 :(得分:1)

GNU find允许您-printf %d列出目录树中文件的深度,而%h列出其名称的前导目录,请参见。 info '(find) Format Directives'

目标文件为pom.xml,我希望以下内容可以执行您想要的操作:对深度进行升序排序,并从第一行返回目录名。如果realpath是绝对的,则可以跳过$root步骤。要求文件名不带制表符或换行符。

v=$(find "${root:-${PWD}}" -type f -name pom.xml -printf '%d\t%h\n' | sort -n | head -n1 | cut -f2)
v=$(realpath -e "$v")