Unix不区分大小写的命令行搜索包含wldcards和空格

时间:2017-09-07 10:06:06

标签: unix

我正在尝试提出一种方法来远程查找AIX UNIX机器上的文件列表,这些文件符合windows中的内容,就像简单的标准一样。它需要不区分大小写(叹气),使用通配符(*)并且可能在路径中包含空格。

对于我下面的测试,我使用的是ksh shell。但是它也需要在ssh shell中工作。

我正在尝试使用plink,命令行和批处理文件在Visual Basic 6(我知道)中实现安全FTP。

基本上找到类似下面的文件,但不区分大小写:

ls -1 -d -p "/test/rick/01012017fosterYYY - Copy.txt" | grep -v '.*/$'

感谢您的帮助。

ls -1 -d -p /test/rick/01012017[Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy] - [Cc][Oo][Pp][Yy].[Tt][Xx][Tt] | grep -v '.*\/$'**

失败了:

ls:0653-341文件/ test / rick / 01012017 [Ff] [Oo] [Ss] [Tt] [Ee] [Rr] [Yy] [Yy] [Yy]做 不存在。 ls:0653-341该文件 - 不存在。 ls:0653-341文件[Cc] [Oo] [Pp] [Yy]。[Tt] [Xx] [Tt]不存在。

ls -1 -d -p /test/rick/01012017[Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy].[Tt][Xx][Tt] | grep -v '.*\/$'**

成功 - 只要没有空格。

ls -1 -d -p "/test/rick/01012017[Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy].[Tt][Xx][Tt]" | grep -v '.*\/$'**

失败了:

ls:0653-341文件/test/rick/01012017[Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy].[T t] [Xx] [Tt]不存在。

- 假设:我们不能使用带通配符的引号

ls -1 -d -p "/test/rick/01012017fosterYYY - Copy.txt" | grep -v '.*\/$'**

成功。不区分大小写。

ls -1 -d -p /test/rick/[0][1][0][1][2][0][1][7][Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy] - [Cc][Oo][Pp][Yy].[Tt][Xx][Tt] | grep -v '.*\/$'**

失败了:

ls:0653-341文件/ test / rick / [0] [1] [0] [1] [2] [0] [1] [7] [Ff] [Oo] [Ss] [Tt ] [EE] [器Rr ] [Yy] [Yy] [Yy] [不存在。 ls:0653-341文件] [ - ] [不存在。 ls:0653-341文件] [抄送] [Oo] [Pp] [Yy]。[Tt] [Xx] [Tt]不存在。

ls -1 -d -p /test/rick/[0][1][0][1][2][0][1][7][Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy][ ][-][ ][Cc][Oo][Pp][Yy].[Tt][Xx][Tt] | grep -v '.*\/$'**

失败了:

ls:0653-341文件/ test / rick / [0] [1] [0] [1] [2] [0] [1] [7] [Ff] [Oo] [Ss] [Tt ] [EE] [器Rr ] [Yy] [Yy] [Yy] [不存在。 ls:0653-341文件] [ - ] [不存在。 ls:0653-341文件] [抄送] [Oo] [Pp] [Yy]。[Tt] [Xx] [Tt]不存在。

ls -1 -d -p /test/rick/01012017[Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy]?-?[Cc][Oo][Pp][Yy].[Tt][Xx][Tt] | grep -v '.*\/$'**

成功。虽然不是很有帮助。

ls -1 -d -p /test/rick/01012017[Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy][ ]-[ ][Cc][Oo][Pp][Yy].[Tt][Xx][Tt] | grep -v '.*\/$'**

失败了:

ls:0653-341文件/ test / rick / 01012017 [Ff] [Oo] [Ss] [Tt] [Ee] [Rr] [Yy] [Yy] [Yy] [d oes不存在。 ls:0653-341文件] - [不存在。 ls:0653-341文件] [抄送] [Oo] [Pp] [Yy]。[Tt] [Xx] [Tt]不存在。

ls -1 -d -p /test/rick/01012017[Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy]{ }-{ }[Cc][Oo][Pp][Yy].[Tt][Xx][Tt] | grep -v '.*\/$'**

失败了:

ls:0653-341文件/ test / rick / 01012017 [Ff] [Oo] [Ss] [Tt] [Ee] [Rr] [Yy] [Yy] [Yy] {d oes不存在。 ls:0653-341文件} - {不存在。 ls:0653-341文件} [抄送] [Oo] [Pp] [Yy]。[Tt] [Xx] [Tt]不存在。

ls -1 -d -p /test/rick/*01012017[Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy] - [Cc][Oo][Pp][Yy].[Tt][Xx][Tt]* | grep -v '.*\/$'**

失败

ls:0653-341文件/ test / rick / 01012017 [Ff] [Oo] [Ss] [Tt] [Ee] [Rr] [Yy] [Yy] [Yy] d oes不存在。 ls:0653-341该文件 - 不存在。 ls:0653-341文件[Cc] [Oo] [Pp] [Yy]。[Tt] [Xx] [Tt] 不存在。

ls -1 -d -p "/test/rick/01012017[Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy] - [Cc][Oo][Pp][Yy].[Tt][Xx][Tt]" | grep -v '.*\/$'**

失败了:

ls:0653-341文件/ test / rick / 01012017 [Ff] [Oo] [Ss] [Tt] [Ee] [Rr] [Yy] [Yy] [Yy] - [Cc] [Oo] [Pp] [Yy]。[Tt] [Xx] [Tt]不存在。

4 个答案:

答案 0 :(得分:2)

ls不进行模式匹配,任何通配符扩展( globbing )都由shell完成。 glob模式语言与正则表达式不同。有关globbing的信息,请阅读ksh文档(联机帮助页中的“文件名生成”)。

所以当你这样做时:

$ touch foo flo fum
$ ls -1 f[ol]o
flo
foo

... shell 注意到通配符[],读取目录内容,用匹配文件替换它,并将这些作为参数传递给ls。您可以使用echo代替:

来显示此信息
$ echo f[ol]o
flo foo

ksh~()构造中提供了全局选项,选项i是“将匹配视为不区分大小写”:

ksh$ touch foo FoO FOO
ksh$ echo ~(i)foo
foo FoO FOO

bash有一个nocaseglob shopt选项:

bash$ shopt -s nocaseglob
bash$ touch fOo
bash$ echo FO*
foo

虽然注意到需要出现一些全球化角色才能实现神奇:

bash$ echo FOO
FOO
bash$ echo [F]OO
foo

(要保持此选项在本地更改,请参阅https://unix.stackexchange.com/questions/310957/how-to-undo-a-set-x/310963

看起来您正在使用grep -v '.*/$'删除作为目录的行。 .*在这里是多余的 - grep -v '/$'是等价的。

find是一种更好的搜索和过滤工具,通过实际查看文件属性来实现-type f(匹配常规文件),而不是通过解析一些ASCII来实现列表。

$ touch foo FOO FoO
$ mkdir fOo
$ find . -maxdepth 1 -type f -iname "foo"
./FOO
./foo
./FoO

答案 1 :(得分:1)

您可以使用find -iname选项来允许不区分大小写的搜索,因此对于您提供以下任何内容的示例,应找到您的文件:< / p>

find /test/rick -maxdepth 1 -iname '01012017fosterYYY - copy.txt'
# or
find /test/rick -maxdepth 1 -iname '01012017fosteryyy - copy.txt'
# or 
find /test/rick -maxdepth 1 -iname '01012017FOSTERyyy - cOpY.txt'
  • -maxdepth 1:不要在子目录中搜索
  • -iname:允许不区分大小写的搜索

答案 2 :(得分:0)

对于不区分大小写的通配符搜索,当-maxdepth和-iname标志不可用于AIX Find时,可以将查找结果传递给Grep:

find /test/rick/. \( ! -name . -prune \) -type f -print | grep -i ".*foster.*\.txt"

找到[InThisFolder] [ExcludeSubfolders] [FileTypes] | grep [InsensitiveWildcardName]

但是,如果您的文件夹结构类似于“/ test / rick / rick /".

,这仍然会有问题。

以下代码给出了当前目录指示符“。”的结果:

find /test/rick/. \( ! -name . -prune \) -type f -print | grep -i ".*foster.*\.txt"

但是你可以将结果传递给sed并找到“/./”并替换为“/".

find /test/rick/. \( ! -name . -prune \) -type f -print | grep -i ".*foster.*\.txt" | sed 's/\/\.\//\//g'

*更新*

基于此页面:http://mywiki.wooledge.org/ParsingLs

我已经提出了以下命令(用于文件扩展或通配的循环),这避免了来自find ||的问题“/ test / rick / rick /”文件夹结构。上面的grep解决方案。它从任何文件夹中搜索文件夹,处理空格并处理不区分大小写,而无需指定转义字符或上/下匹配([Aa])。

只需修改searchfolder和searchpattern:

searchfolder="/test/rick"; searchpattern="*foster*.txt"; for file in "$searchfolder"/*.*; do [[ -e "$file" ]] || continue; if [[ "$(basename "$file" | tr '[:upper:]' '[:lower:]')" = $searchpattern ]]; then echo "$file"; fi; done

这样做:

  • 设置要搜索的文件夹路径(searchfolder="/test/rick";
  • 设置搜索模式(searchpattern="*foster*.txt"
  • 循环搜索文件夹(for file in "$searchfolder"/*.*;
  • 上的每个文件
  • 确保文件存在([[ -e "$file" ]] || continue;
  • 将任何基本文件名大写字符转换为小写(basename "$file" | tr '[:upper:]' '[:lower:]'
  • 测试降低的基本文件名是否与搜索模式匹配,如果是, 然后打印完整路径和文件名(if [[ $(basename "$file" | tr '[:upper:]' '[:lower:]') = $searchpattern ]]; then echo "$file"; fi;

在ksh(版本M-11/16 / 88f)和ksh93(版本M-12/28 / 93e)的AIX(版本6.1.0.0)上测试。

答案 3 :(得分:0)

我最终使用的(因为我无法访问-maxdepth或-iname)只是使用不区分大小写的通配符和空格周围的引号。

ls -1 -d -p /test/rick/01012017[Ff][Oo][Ss][Tt][Ee][Rr][Yy][Yy][Yy]' '-' '[Cc][Oo][Pp][Yy].[Tt][Xx][Tt] | grep -v '.*\/$'

这样我就不必安装或升级任何东西,可能会导致更多问题,因此我可以获得一个简单的文件列表。

注意:如果路径下有任何子目录,AIX UNIX仍会引发一些乱码错误。我点了这个,只是在客户端解析了这些无用的消息。

感谢所有回复的人。