修复文件路径大小写

修复文件路径大小写

我有一个存储文件路径的列表,即(impl/src/main/java/org/jboss/weld/util/collections/multimaps.java)。在存储之前,路径已转换为小写。

现在,我需要在 bash 脚本中访问该文件。有没有一个简单的命令来“修复”外壳并找到文件?为简单起见,假设该文件不存在具有不同情况的多个版本。另请注意,路径中的目录可能需要修复其大小写。

我考虑过使用 find,但您不能拥有完整路径,因此从根目录find . -iname multimaps.java可能会返回多个文件,其中只有一个文件位于正确的目录结构中。

我需要正确的路径以最终出现在 bash 脚本中的变量中。

答案1

GNUfind有一个-iwholename谓词可以解决我的问题:

find . -iwholename ./impl/src/main/java/org/jboss/weld/util/collections/multimaps.java

要将其放入变量中:

cased=`find . -iwholename "$filepath"`

答案2

zsh

setopt extendedglob
files=((#i)${(f)^"$(<file.list)"}(N))
printf '%s\n' $files

(其中file.list包含小写路径列表的文件,每行一个)。

  • (#i): 不区分大小写的 glob (需要extendedglob)
  • ${(f)"$expansion"}:在换行符上拆分扩展(换行符)
  • ${^array}:对数组进行大括号扩展类型的扩展。
  • (N): nullglob glob 限定符(删除不匹配的 glob)。

对于单个文件,它只是:

setopt extendedglob
file=impl/src/main/java/org/jboss/weld/util/collections/multimaps.java
matches=((#i)$file)

(这里省略了,(N)所以如果没有匹配的话你会得到一个错误)

等价的ksh93是:

matches=(~(iN)"$file") # N for nullglob, otherwise the glob expands to itself
                       # instead of giving an error when it doesn't match.

bash有一个nocaseglob不区分大小写的选项。然而

匹配=($文件)

行不通的。你需要启用对每个路径组件进行通配(通过使用任何通配符运算符),如

shopt -s nocaseglob nullglob
matches=([i]mpl/[s]rc/[m]ain/[j]ava/[o]rg/[j]boss/[w]eld/[u]til/[c]ollections/[m]ultimaps.java)

对于任何支持[...]glob 运算符的 shell(因此本质上,除了fish),您还可以将 glob 重写为[iI][mM][pP][lL]/[sS][rR]...等等。

请注意,它与 a 不同find . -ipath "./$file",shell 不需要爬行整个目录树。它首先读取当前目录以查找目录(或目录的符号链接!另一个区别find)称为implorImplImPl等,然后仅读取这些目录的内容以查找一些src//SRCsrC

另一个区别是,如果路径组件恰好包含全局运算符(例如impl/***src***/whatever),它仍然可以正常工作。

答案3

在bash中:

shopt -s nocasematch globstar
for f in **; do for search in "${files[*]}"; do [[ $f == $search ]] && echo Found "$search" at: "$f"; done; done

nocasematch shell 选项告诉[[ ... == ... ]]命令在比较字符串时忽略大小写。 globstar shell 可以进行**强力 bash 模拟find;它的不同之处find在于它将跳过点文件(除非shopt -s dotglob设置)并遵循符号链接。

答案4

避免为每个文件一次又一次扫描树的方法是列出目录树一次,然后在哈希表中查找路径的小写翻译。例如:

NL='
'
find . -name "*$NL*" -prune -o -print | awk '
  !list_processed {paths["./" $0]; next}
  tolower($0) in paths' file.list list_processed=1 -

(其中file.list包含小写文件列表,每行一个)。

我们将跳过名称中带有换行符的文件(而不是进入目录),因为如果该列表是换行符分隔的,则它们不可能存储在列表中file.list(并且会破坏后处理)。

但请注意,如果文件名也包含无效字符,则跳过将不起作用。请参阅字节与字符部分位于为什么循环查找的输出是不好的做法?更多细节。

相关内容