AWK:从LS获取文件名

时间:2018-07-12 12:55:51

标签: regex awk

我有一个文件名列表(名称加扩展名),我只想提取不带扩展名的文件名。

我正在使用

ls -l | awk '{print $9}' 

列出文件名,然后

ls -l | awk '{print $9}' | awk /(.+?)(\.[^.]*$|$)/'{print $1}'

但是在转义(时出现错误:

-bash: syntax error near unexpected token `('

用于分隔名称的正则表达式(.+?)(\.[^.]*$|$)有一个捕获组,我认为这是正确的,尽管我不知道它在awk语法中不起作用。

我的文件列表类似于ABCDEF.ext在根文件夹中。

4 个答案:

答案 0 :(得分:4)

您的特定错误是由于awk命令引用错误而引起的。单引号应该放在整个命令中,而不仅仅是{ action }块。

但是,您不能使用awk中的捕获组。 $1指第一个字段,由输入字段分隔符定义(在这种情况下,默认值为:一个或多个“空白”字符)。与正则表达式中的括号无关。

此外,您不应该从ls -l开始处理文件。我认为在这种情况下,最好的选择是使用Shell循环:

for file in *; do
  printf '%s\n' "${file%.*}"
done

这使用外壳程序的内置功能将*扩展到当前目录中的所有内容列表,并使用标准参数扩展从每个名称的末尾删除.*


如果由于某些原因您确实真的想使用awk,并且所有文件都具有相同的扩展名.ext,那么我想您可以执行以下操作:

printf '%s\0' * | awk -v RS='\0' '{ sub(/\.ext$/, "") } 1'

这将打印当前目录中的所有路径,并使用awk删除后缀。每个路径后跟一个空字节\0-这是传递路径列表的安全方法,原则上路径列表可以包含其他任何字符。

健壮性稍差一些,但在大多数情况下可能还不错,那就是相信没有文件名包含换行符,并使用\n来分隔列表:

printf '%s\n' * | awk '{ sub(/\.ext$/, "") } 1'

请注意,将使用sed这样的用于简单替换的标准工具:

printf '%s\n' * | sed 's/\.ext$//'

答案 1 :(得分:1)

(.+?)是PCRE构建体。 awk使用ERE,而不使用PCRE。此外,在脚本开始之前,条件之后(而不是条件所属的位置),在脚本中间会有一个打开的脚本定界符'

任何命令(awk,sed,grep等)的语法均为command 'script',因此应为awk 'condition{action}',而不是awk condition'{action}'

但是,无论如何,正如@Aaron在评论中提到的-不要解析ls的输出,请参见http://mywiki.wooledge.org/ParsingLs

答案 2 :(得分:-2)

如果扩展名总是相同的模式,请尝试使用sed替换:

ls -l | awk '{print $9}' | sed 's\.ext$\\'

答案 3 :(得分:-2)

尝试一下。

ls -l | awk '{ s=""; for (i=9;i<=NF;i++) { s = s" "$i }; sub(/\.[^.]+$/,"",s); print s}'

注意:

  1. 读取ls -l输出很奇怪
  2. 它不检查项目(它们是文件吗?目录?到处都是扩展区)
  3. 阅读其他答案:D