1

我正在尝试对 ls 的输出进行排序。我要的顺序是这样的:

  • 任何名称以 _ 开头的目录
  • 任何名称以 + 开头的目录
  • 所有软链接(可能包括一些点文件)
  • 所有剩余的 .files
  • 所有剩余的 .directories
  • 其他一切

在这些“子列表”中,所有内容都按字母顺序排序。目前我多次使用 find 命令来查找符合上述条件的文件。之后,我将 find 的输出通过管道传递给 sort,然后将整个排序列表传递给 ls:

#!/bin/bash

find1=`find . -maxdepth 1 -name "_*" -type d -printf "%f\n" | sort`
find2=`find . -maxdepth 1 -name "+*" -type d -printf "%f\n" | sort`
find3=`find . -maxdepth 1 -type l -printf "%f\n" | sort`
find4=`find . -maxdepth 1 -name ".*" -type f -printf "%f\n" | sort`
find5=`find . -maxdepth 1 \( ! -name "."  \) -name ".*" -type d -printf "%f\n" | sort`
find6=`find . -maxdepth 1 \( ! -name "_*" \) \( ! -name "+*" \) \( ! -name ".*" \) \( ! -type l \) -printf "%f\n"`
find="$find1 $find2 $find3 $find4 $find5 $find6"
ls -dfhlF --color=auto $find

这不处理任何包含空格的名称,总体上看起来有点过分。我确信有更好的方法来做到这一点。有任何想法吗?

4

1 回答 1

0

Will this work for you? It prints the files in the order you specified, but it won't print them in color. In order to do that, you'd need to strip the ANSI codes from the names before pattern-matching them. As it is, it will handle filenames with embedded spaces, but not horribly pathological names, like those with embedded newlines or control characters.

I think the awk script is fairly self-explanatory, but let me know if you'd like clarification. The BEGIN line is processed before the ls output starts, and the END line is processed after all the output is consumed. The other lines start with an optional condition, followed by a sequence of commands enclosed in curly brackets. The commands are executed on (only) those lines that match the condition.

ls -ahlF --color=none | awk '
  BEGIN { name_col = 45 }
  { name = substr($0, name_col) }
  name == "" { next }
  /^d/ && substr(name, 1, 1) == "_" { under_dirs = under_dirs $0 "\n"; next }
  /^d/ && substr(name, 1, 1) == "+" { plus_dirs = plus_dirs $0 "\n"; next }
  /^l/ { links = links $0 "\n"; next }
  /^[^d]/ && substr(name, 1, 1) == "." { dot_files = dot_files $0 "\n"; next }
  /^d/ && substr(name, 1, 1) == "." { dot_dirs = dot_dirs $0 "\n"; next }
  { others = others $0 "\n" }
  END { print under_dirs plus_dirs links dot_files dot_dirs others }
'
于 2013-08-31T13:14:01.417 回答