命令:
ls /some/path/some/dir/ | grep some_mask_*.txt | wc -l
通过bash上的ssh执行此操作时,返回正确数量的文件。当我把它放入.sh脚本
时iFiles=`ls /some/path/some/dir/ | grep some_mask_*.txt | wc -l`
echo "iFiles: ${iFiles}"
总是0
。这有什么不对吗?
解决方案:
当我研究它时,我发现我的“通配符掩码”似乎是问题所在。使用grep some_mask_ | grep \.txt
而不是上面的单个grep帮我解决了第一个问题。
我将答案标记为解决方案,几乎完全描述了我犯了什么错误。我现在要编辑我的脚本。谢谢大家。
答案 0 :(得分:6)
Parsing ls is not a good thing。如果您要查找文件,请使用find
:
find /some/path/some/dir/ -maxdepth 1 -name "some_mask_*.txt" -print0
这将打印与该目录中的条件匹配的文件,而不会进入子目录。当文件名不包含常见字符时,使用print0
可防止出现奇怪的情况:
-print0
True; print the full file name on the standard output, followed
by a null character (instead of the newline character that
-print uses). This allows file names that contain newlines or
other types of white space to be correctly interpreted by pro‐
grams that process the find output. This option corresponds to
the -0 option of xargs.
然后,只需输入wc -l
即可获得最终计数。
顺便说一句,请注意
ls /some/path/some/dir/ | grep some_mask_*.txt
可以简化为简单的
ls /some/path/some/dir/some_mask_*.txt
答案 1 :(得分:3)
我建议使用find
,如下所示。原因是文件名可能包含会破坏正在使用wc -l
的脚本的换行符。我只为每个文件名打印一个点,并用wc -c
计算点数:
find /some/path/some/dir/ -maxdepth 1 -name 'some_mask_*.txt' -printf '.' | wc -c
或者如果您想将结果写入变量:
ifiles=$(find /some/path/some/dir/ -maxdepth 1 -name 'some_mask_*.txt' -printf '.' | wc -c)
答案 2 :(得分:2)
这里的问题是grep some_mask_*.txt
是由shell而不是grep扩展的,所以很可能你在执行grep的目录中有一个匹配some_mask_*.txt
的文件,然后使用该文件名通过grep作为过滤器。
如果要确保grep使用该模式,则需要将其用单引号括起来。此外,您需要将模式编写为正则表达式而不是通配符匹配(bash用于匹配)。将命令行版本放在一起应该是:
ls /some/path/some/dir/ | grep 'some_mask_.*\.txt' | wc -l
和脚本:
iFiles=`ls /some/path/some/dir/ | grep 'some_mask_.*\.txt' | wc -l`
echo "iFiles: ${iFiles}"
请注意,.
需要以反斜杠作为前缀,因为它具有与单个字符匹配的正则表达式的特殊意义。
我还建议您使用$后缀regexp以便将其锚定到最后(从而确保正则表达式匹配以" .txt"结尾的文件名):
ls /some/path/some/dir/ | grep 'some_mask_.*\.txt$' | wc -l
答案 3 :(得分:1)
简单的解决方案是(对于bash)
find -name "*pattern*" | wc -l
答案 4 :(得分:0)
试试这个,
iFiles=$(ls /some/path/some/dir/ | grep some_mask_*.txt | wc -l)
echo "iFiles: ${iFiles}"
答案 5 :(得分:0)
我认为不会出现shell版本问题。
尝试在命令中使用escape char。它喜欢以下。
ls /some/path/some/dir/ | grep some_mask_\*.txt | wc -l
答案 6 :(得分:0)
您的问题是由于 shell扩展造成的。您可能在原始目录中测试了命令行,但是如果您从另一个目录中尝试它,那么它将不再起作用。
键入时:
grep *.txt
然后shell将*.txt
替换为与模式对应的所有文件名,然后执行命令(类似grep a.txt dummy.txt
)。但是您希望模式由grep
解释,而不是由shell扩展,所以:
ls /tmp | grep '.*.cpp'
威尔做到了。这里的模式使用grep
命令的语法(每个命令作为自己的语法)和未扩展,因为它受到环境'
的保护。
修改您的命令,如:
a=`ls /tmp | grep '.*.cpp'`
答案 7 :(得分:0)
这与其他答案非常相似,但具有更强的稳健性
iFiles=$( find /some/path/ -name "some_mask_*.txt" -type f 2> /dev/null | wc -l )
echo "Number of files: $iFiles"
这会限制查找文件并将stderr管道为null,因此如果find命令不起作用或有权限问题,则不会出现虚假结果。
答案 8 :(得分:-2)
我正在编写一个Shell脚本来计算目录中相同格式的文件。为此,我使用了以下命令
LOCATION=/home/students/run_date/FILENAME #stored the location in a variable
DIRECTORYCOUNT=$(find $LOCATION -type d -print | wc -l) using find command
DIRECTORYCOUNT=$(find $LOCATION -type f -print | wc -l)
我已经使用了上面的命令并在此处输入了很好的代码