当我在做的时候
ls -la |grep -e Aug
我得到的输出为
-rw-r--r-- 1 root staff 454 Oct 15 18:35 Aug.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 25 04:00 abc7.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 26 07:00 def7.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 27 10:00 ghi7.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 28 13:00 jkl7.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 29 16:00 mno7.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 30 19:00 pqr7.txt
我只想列出 8 月创建的文件,而不是列出 10 月创建但名称为 8 月的第一个文件。下面应该是输出
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 25 04:00 abc7.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 26 07:00 def7.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 27 10:00 ghi7.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 28 13:00 jkl7.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 29 16:00 mno7.txt
-rwxr-xr-x@ 1 PrashastKumar staff 0 Aug 30 19:00 pqr7.txt
另外,我想将月份作为用户输入而不是硬编码值。
答案1
您应该考虑替代方案解析ls
,即充满多重陷阱。但是,由于您在这里的主要兴趣似乎是如何按列进行过滤,并且您的最终目标可能不是ls
无论如何解析,所以我将继续并坚持您正在使用的示例(使用ls
)。不过,请不要认为这意味着解析ls
输出是一件好事。这通常不是一件好事。
当您grep
for时Aug
,您正在一行中的任何位置搜索它。实际上,您不想选择包含Aug
任何位置的行,而只想选择那些将其作为第六列的完整且准确文本的行。虽然你能这样做grep
会更容易、更自然awk
:
ls -la | awk '$6 == "Aug"'
如果由于某种原因你真的想要执行此操作grep
,您可以:
ls -la | grep -E '(\S+\s+){5}Aug\s'
你是也有兴趣过滤第六列等于已读入 shell 变量的值的行month
。您已经观察到这确实不是工作:
ls -la | awk '$6 == "$month"' # does not work
不起作用的原因是单引号AWK 脚本周围$6 == "$month"
阻止 shell 执行参数扩展将$month
其替换为其值。文本$month
按原样传递到awk
,这不是您想要的。AWK 变量和 shell 变量是完全分开的。解决此问题的一种干净而简单的方法是使用命令awk
的-v
选项从 shell 变量初始化 AWK 变量:
ls -la | awk -v m="$month" '$6 == m'
如果您愿意,您可以将 AWK 变量命名为与 shell 变量相同的名称。在这种它们代表相同事物的情况下,这是一个合理的选择。我将 AWK 变量命名为m
,以说明 shell 和 AWK 变量如何分开并避免混淆。 (对于长或复杂的 AWK 脚本,或者具有许多变量的脚本,您可能希望以更具描述性的方式命名变量m
,而不仅仅是 ,但在这种情况下,不会牺牲可读性。)
我在上面链接了主题Bash 参考手册因为你已经标记了你的问题操作系统除了最古老的 OS X 版本(现在称为 macOS)之外,所有版本的默认 shell 都是bash
.在非常旧的版本中是tcsh
.
作为旁注,您提到您使用month
命令将 的值作为输入read month
。当您使用 shell 的read
命令时,您几乎应该总是传递该-r
标志,从而改为 write read -r month
。仅-r
当您省略时想read
翻译\
它收到的输入中的转义命令(您实际上永远不想要这种情况)。您可能还想使用IFS= read -r month
,因此前导和尾随空格不会被删除。但在这种情况下,您可能确实希望将其删除,因此可以省略IFS=
.
答案2
这对我有用
ls -al | awk '$6 == "Aug" {print}'