在shell脚本中列出文件

Akh*_*yil 7 linux bash shell

当我尝试下面的代码时,我将获取所有文件名以E开头的文件

#!/bin/bash

data=$(ls -trh E*)
for entry in ${data}
do
  echo ${entry}
done
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试下面的代码,从参数获取通配符,我只获得第一个文件名

#!/bin/bash

data=$(ls -trh $1)
for entry in ${data}
do
  echo ${entry}
done
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮我解决这个问题..

当我给像myscript.sh'E*'这样的引号时,它工作得很好,有没有办法在没有报价的情况下做到这一点?

bri*_*ice 7

这是一个shell扩展问题.

在传递给您的进程之前,您的shell将解释通配符.例如:

script.sh

#!/bin/bash
echo $1 $2 $3
Run Code Online (Sandbox Code Playgroud)

使用通配符运行上面的代码:

> ./script.sh E*
Eva   Eve   Evolve
Run Code Online (Sandbox Code Playgroud)

如果你想在没有shell的情况下首先解释它,你必须引用它:

> ./script.sh 'E*'
E*
Run Code Online (Sandbox Code Playgroud)

更好的解决方案find:

您实际要做的是获取给定目录中所有文件和文件夹的列表,反向修改时间顺序(最早的第一个).输出ls是非常痛苦的解析.最好使用强大而灵活的find命令.

这是一个班轮:

>  find ./ -maxdepth 1 -printf "%A@ %f\0" | sort -z -n | while read -d '' date line; do echo "$line"; done
Run Code Online (Sandbox Code Playgroud)

这可能是神秘的,但一旦解释就有意义.

  • 查找此目录中的所有文件而不进行递归 find ./ -maxdepth 1
  • 对于每个文件,以秒为单位打印出上次修改时间 -printf "%A@
  • 和它们的文件名,用空字符分隔 %f\0"
  • 按上次修改时间(以数字方式)对空值分隔的字符串进行排序 sort -z -n
  • 对于每个以null为单位的字符串,将时间戳指定为"date",将该行的其余部分指定为"line": while read -d '' date line
  • 打印线 echo "$line"

例如,在我的目录中:

> ls -l
total 4296
drwxr-xr-x 2 bfer cvs    4096 2012-03-05 15:49 colortry
drwxr-xr-x 3 bfer cvs    4096 2012-03-27 15:05 githug
drwxr-xr-x 3 bfer cvs    4096 2012-03-12 17:18 hooks-bare
drwxr-xr-x 3 bfer cvs    4096 2012-03-28 12:38 java
-rw-r--r-- 1 bfer cvs 4025413 2012-03-27 12:53 mozdebug
drwxr-xr-x 2 bfer cvs    4096 2012-02-16 12:54 mustache_bug_demo
-rwxr-xr-x 1 bfer cvs     113 2012-03-30 12:20 try.sh
> find ./ -maxdepth 1 -printf "%A@ %f\0" | sort -z -n | while read -d '' date line; do echo "$line"; done
mozdebug
colortry
hooks-bare
mustache_bug_demo
githug
java
try.sh
./
Run Code Online (Sandbox Code Playgroud)

如果您不想要./结果,只需将其从最终设置中取出即可.

更新: Sorpigal建议使用换行符处理文件名.

关于壳扩展的进一步说明

这与括号和&符号相同.例如,以下curl命令将无法按预期工作:

> curl example.com/site?q=hello&name=bob
> echo 23/(7/98) | bc
Run Code Online (Sandbox Code Playgroud)

因为&符号和括号将在它们作为参数传递给进程之前由shell解释.

为了使其正常工作,您必须引用args:

> curl "example.com/site?q=hello&name=bob"
> echo "23/(7/98)" | bc
Run Code Online (Sandbox Code Playgroud)