有没有一种快速简单的方法可以在 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
。