在 bash 中描述/标记文件的简单方法

在 bash 中描述/标记文件的简单方法

有没有一种快速简单的方法可以在 bash 中标记文件,以便像这样的列表

-rw------- 1 root   88039 Sep 29 16:31 7CCE2EC3-3191-4379-C036-1C48CCCE4C6C
-rw------- 1 root 1985554 Sep 27 16:09 61C6DCDC-04C6-5137-8894-2C8930251D1E
-rw------- 1 root  248965 Sep 26 14:12 22384DC7-D60E-57CC-94C2-C5301C980990
-rw------- 1 root  293908 Sep 22 18:27 C14E6C74-C301-49CC-C625-070721CC47C1
-rw------- 1 root  120965 Sep 19 19:17 2407C1C5-D09C-41E1-9080-C2CC8C86D0CC
-rw------- 1 root   20036 Sep 13 18:32 78691D77-C4E6-4ED1-8119-C09CCC194892
-rw------- 1 root   11789 Sep 12 23:16 8C8C190C-5340-421C-96D1-D4111C5E062C
-rw------- 1 root    1884 Sep 11 22:07 CCC91959-9744-4339-9C99-0C75E301090C

变成这样(或类似)

-rw------- 1 root   88039 Sep 29 16:31 7CCE2EC3-3191-4379-C036-1C48CCCE4C6C
-rw------- 1 root 1985554 Sep 27 16:09 61C6DCDC-04C6-5137-8894-2C8930251D1E
-rw------- 1 root  248965 Sep 26 14:12 22384DC7-D60E-57CC-94C2-C5301C980990 -> MYOLDFILE1
-rw------- 1 root  293908 Sep 22 18:27 C14E6C74-C301-49CC-C625-070721CC47C1
-rw------- 1 root  120965 Sep 19 19:17 2407C1C5-D09C-41E1-9080-C2CC8C86D0CC -> MYNEWFILE.TXT
-rw------- 1 root   20036 Sep 13 18:32 78691D77-C4E6-4ED1-8119-C09CCC194892
-rw------- 1 root   11789 Sep 12 23:16 8C8C190C-5340-421C-96D1-D4111C5E062C -> hello.c
-rw------- 1 root    1884 Sep 11 22:07 CCC91959-9744-4339-9C99-0C75E301090C

我尝试做了一些事情ln -s,但最终却得到了很多重复项,因为链接在同一个目录中,为了获得良好的视图,我必须使用 grep 过滤 ls。如能得到任何帮助,不胜感激

答案1

我认为您无法可靠地(误用)任何可用功能来使常规ls(带或不带选项)执行您想要的操作。您需要ls使用脚本、函数或别名重新定义。

我不会重新定义ls它自己,至少在这个例子中不会,因为它本来是简单的概念证明。支持命令行开关ls会使示例过于复杂。

为了实现我的解决方案,您需要一个支持扩展属性的文件系统和操作它们的工具(例如apt-get install attr在 Debian 中)。

要设置属性:

setfattr -n user.mytag -v "hello.c" "8C8C190C-5340-421C-96D1-D4111C5E062C"

注意:mytag是任意名称。选择一个并坚持使用。

要删除该属性:

setfattr -x user.mytag "8C8C190C-5340-421C-96D1-D4111C5E062C"

您可以构建自定义脚本或函数,以更方便的方式执行这些操作。现在假设您选择ll执行您想要的操作。如果它是一个别名,您需要先取消别名:

unalias ll

然后定义一个函数:

function ll() { find "$@" -maxdepth 1 -exec \
   sh -c '
      a=$(getfattr -n user.mytag --only-values "$1" 2>/dev/null)
      ls -dalF -- "$1" | tr -d "\n"
      if [ -z "$a" ]; then printf "\n"; else printf " => %s\n" "$a"; fi
   ' sh {} \;
}

使用示例:

ll   # but see notes below
ll 8C8C190C-5340-421C-96D1-D4111C5E062C
ll /bin
ll foo.txt bar.txt

示例输出:

-rw------- 1 root root 11789 Sep 12 23:16 8C8C190C-5340-421C-96D1-D4111C5E062C => hello.c

笔记:

  • 我使用了=>,而不是->,因为后者已经被ls符号链接使用。
  • POSIX 要求调用时至少有一个路径find。单独ll(无参数)可能会导致find失败(比较这个答案)。如果是这样,您将需要一些初步的逻辑来传递.find
  • -maxdepth也不是 POSIX。如果你不能使用它,请参阅这个问题
  • 该函数只是将其所有参数传递给find(作为"$@")。这意味着此自定义ll不理解ls(或常用ll别名)通常使用的选项。另一方面,将测试注入find是可能的。
  • 名称或标签中的特殊或不可打印的字符可能会导致意外的输出。
  • ls -dalF针对每个对象分别调用,因此生成的行可能不会对齐到常规列中。考虑使用-printf操作而不是ls打印所需的所有信息,但标签除外,标签仍需要getfattr。在格式中使用制表符作为分隔符-printf将使多行输出列化(至少在某种程度上)。请注意,使用正确的-printf格式,您将不需要tr

相关内容