试图解决这个问题append wc...我无法理解如何捕获作为awk命令参数传递的文件名。
awk 'BEGIN {for ( i=1;i<ARGC;i++ )print "ARGV " i ": [" ARGV[i] "]" }
FNR==1 {print "FILENAME " ++a ": [" FILENAME "]" }
' $( ls )
适用于标准文件名,例如file1.txt
,但是间隔文件名lile file with space
会出现问题(实际上当文件名包含$ IFS字符且IFS不是要触摸)。 FILENAME没问题,ARGV在空格上是分开的(引用或不引用),就好像在shell传递后将所有参数解析为一个字符串一样。
我使用它来计算文件行,即使文件是空的(因此永远不会达到FNR == 1),但这不是问题。
所以
$( ls | sed "s/'/'\"'\"'/g;s/.*/'&'/")
这样的引用,但没有帮助)我在linux和AIX上使用awk(在这种情况下不是gawk :-()
一些样本
#ls -1 file*
file
file and space
file'qu .txt
file"qu .txt
# awk '...' "file and space"
ARGV 1: [file and space]
FILENAME 1: [file and space]
# awk '...' $( ls file* | sed -e 's/ /?/g' )
ARGV 1: [file]
ARGV 2: [file and space]
ARGV 3: [file'qu .txt]
ARGV 4: [file"qu .txt]
FILENAME 1: [file]
FILENAME 2: [file and space]
FILENAME 3: [file'qu .txt]
最后ls显示awk可能有所不同(文件“qu .txt 是一个空文件,因此FNR == 1永远不会到达)。
我现在看到这是在shell传递信息级别,而不是awk。
答案 0 :(得分:4)
问题与awk
无关,而与 shell (如何传递文件名)无关:
不带引号的命令替换$( ls )
将扩展为文件名列表,但文件名受字拆分,因此带有嵌入空格的文件名每个都被分成多个传递给awk
的参数。
这会导致awk
看到不存在的文件名(此时发生致命错误)或意外处理不同的文件(多次);例如,如果文件file one
,file
和one
都存在于当前目录中,则awk
将不处理file one
,并且而是两次处理file
和one
。
在这种情况下,一个简单的glob(*
)将,其扩展结果不受制于工作分割,并且通常优于解析ls
输出:
awk 'BEGIN {for ( i=1;i<ARGC;i++ )print "ARGV " i ": [" ARGV[i] "]" }
FNR==1 {print "FILENAME " ++a ": [" FILENAME "]" }
' *
使用不带引号的命令替换扩展为传递给命令的多个参数(command $(...)
)通常是一种反模式,因为结果输出不仅受到 - 分裂,但也是 globbing (文件名扩展),作为所谓的shell expansions的一部分。
诊断问题:
$ touch file 'file 1'
$ bash -s - $(ls file 'file 1') <<<'echo "$# args passed: [$1] [$2] [$3]"'
3 args passed: [file] [file] [1]
请注意,即使file 1
与引号一起传递,目标命令(ad-hoc bash脚本)也会看到 3 参数,因为shell已损坏{{ 1}}由于不加引号使用file 1
(命令替换)而成为单独的参数file
和1
(分词)。
(注意$(...)
没有帮助,因为命令输出总是作为单个参数传递。)
以下简化命令会导致"$(...)"
从根本上失败,因为它不会看到单个文件名awk
,而是会看到文件名File One
和File
,两者都不存在:
One
以上是 GNU $ rm -f File One; echo 'hi from File One' > 'File One'
$ awk '{ print FILENAME }' $(ls 'File One')
awk: fatal: cannot open file `File' for reading (No such file or directory)
的错误消息; BSD Awk和Mawk基本上表现相同,除了错误消息的措辞的变化。在这种情况下,所有这些实现都将退出代码设置为awk
。
答案 1 :(得分:1)
这会在你的特定shell中起作用吗?
declare -a files=(*)
awk 'BEGIN {for ( i=1;i<ARGC;i++ )print "ARGV " i ": [" ARGV[i] "]" }
FNR==1 {print "FILENAME " ++a ": [" FILENAME "]" }
' "${files[@]}"
阵列扩展也应该回避你的问题,希望如此。