我有一个文件名列表(名称加扩展名),我只想提取不带扩展名的文件名。
我正在使用
ls -l | awk '{print $9}'
列出文件名,然后
ls -l | awk '{print $9}' | awk /(.+?)(\.[^.]*$|$)/'{print $1}'
但是在转义(
时出现错误:
-bash: syntax error near unexpected token `('
用于分隔名称的正则表达式(.+?)(\.[^.]*$|$)
有一个捕获组,我认为这是正确的,尽管我不知道它在awk语法中不起作用。
我的文件列表类似于ABCDEF.ext
在根文件夹中。
答案 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}'
注意: