我有一个文件名列表(名称加扩展名),我只想提取不带扩展名的名称。
我在用着
ls -l | awk '{print $9}'
Run Code Online (Sandbox Code Playgroud)
列出文件名,然后
ls -l | awk '{print $9}' | awk /(.+?)(\.[^.]*$|$)/'{print $1}'
Run Code Online (Sandbox Code Playgroud)
但我在转义时遇到错误(:
-bash: syntax error near unexpected token `('
Run Code Online (Sandbox Code Playgroud)
隔离名称的正则表达式(.+?)(\.[^.]*$|$)有一个捕获组,我认为它是正确的,但我不知道它在 awk 语法中不起作用。
ABCDEF.ext我的文件列表在根文件夹中是这样的。
您的具体错误是由于您的 awk 命令被错误引用而引起的。单引号应该围绕整个命令,而不仅仅是{ action }块。
但是,您不能像 awk 中那样使用捕获组。$1指由输入字段分隔符定义的第一个字段(在本例中是默认值:一个或多个“空白”字符)。它与正则表达式中的括号无关。
此外,您不应该从ls -l处理文件开始。我认为在这种情况下,最好的选择是使用 shell 循环:
for file in *; do
printf '%s\n' "${file%.*}"
done
Run Code Online (Sandbox Code Playgroud)
这使用 shell 的内置功能来扩展*当前目录中所有内容的列表,并.*使用标准参数扩展从每个名称的末尾删除 。
如果您出于某种原因确实想使用 awk,并且所有文件都具有相同的扩展名.ext,那么我想您可以执行以下操作:
printf '%s\0' * | awk -v RS='\0' '{ sub(/\.ext$/, "") } 1'
Run Code Online (Sandbox Code Playgroud)
这会打印当前目录中的所有路径,并使用 awk 删除后缀。每个路径后面都跟着一个空字节\0- 这是传递路径列表的安全方法,原则上可以包含任何其他字符。
稍微不太健壮但在大多数情况下可能很好的是相信没有文件名包含换行符,并用于\n分隔列表:
printf '%s\n' * | awk '{ sub(/\.ext$/, "") } 1'
Run Code Online (Sandbox Code Playgroud)
请注意,像这样的简单替换的标准工具是 sed:
printf '%s\n' * | sed 's/\.ext$//'
Run Code Online (Sandbox Code Playgroud)