我将给出两个示例解决方案:
一个更简单的单行命令,因此我会先尝试使用它。
一个 bash 脚本,允许通过读取列表的每一行作为输入的任意 bash 函数的输出对列表进行排序。
示例1(每行不执行命令)
如果问题是一般情况下如何对ls 等程序的输出进行排序,下面是一个特定于ls 的示例,它按inode 排序。但是,每个程序在生成其输出时都可能有自己的特点,因此可能需要修改此示例:
ls -ail /home/user/ | tail -n+2 | tr -s ' ' | sort -t' ' -k1,1 -g
以下是此命令的不同部分:
ls -ail /home/user/
使用 inode (-i) 以列表 (-l) 格式列出目录 /home/user/ 中的所有 (-a) 文件。
tail -n+1
从 ls 输出中截断第一行。
tr -s ' '
为 sort 组合 (-s) 多个空格 (' ')。
sort -t ' ' -k 1 -g
按由一个空格 (' ') 分隔的整数 (-g) 的第一个 (1) 字段对列表进行排序。
示例2(以每一行为输入执行命令)
这是我编写的 bash 脚本中的一个更具适应性的示例,用于展示如何将 ls -a1 生成的文件列表输入 bash 函数 getinode,该函数使用 stat 输出每个文件的 inode。 while 循环对每个文件重复此过程,通过重复附加名为 OUTPUT 的变量以逗号分隔格式保存数据,该变量最后使用第一个字段按 sort 排序。
重要的部分是函数getinode可以是任何东西,只要它输出一个字符串。我设置getinode 接收文件路径作为输入(第一个参数$1),然后通过echo $INODE 将inode 输出到stdout。脚本通过$(getinode "$FILEPATH")调用getinode。
#!/bin/bash
# Usage: lsinodesort.sh [file]
# Refs/attrib:
# [1]: How to sort a csv file by sorting on a single field. https://stackoverflow.com/a/44744800
# [2]: How to read a while loop variable. https://stackoverflow.com/a/16854326
WORKDIR="$1" # read directory from first argument
getinode() {
# Usage: getinode [path]
INODE="$(stat "$1" --format=%i)"
echo $INODE
}
if [ -d "$WORKDIR" ]; then
LINES="$(ls -a1 "$WORKDIR")" # save `ls` output to variable LINES
else
exit 1; # not a valid directory
fi
while read line; do
path="$WORKDIR"/"$line" # Determine path.
if [ -f "$path" ]; then # Check if path is a file.
FILEPATH="$path"
FILENAME="$(basename "$path")" # Determine filename from path.
FILEINODE=$(getinode "$FILEPATH") # Get inode.
OUTPUT="$FILEINODE"",""$FILENAME""\n""$OUTPUT" ; # Append inode and file name to OUTPUT
fi
done <<< "$LINES" # See [2].
OUTPUT=$(printf "${OUTPUT}" | sort -t, -k1,1) # sort OUTPUT. See [1]
OUTPUT="inode","filename""\n""$OUTPUT"
printf "${OUTPUT}\n" # print final OUTPUT.
当我在自己的主文件夹上运行它时,我会得到如下输出:
inode,filename
3932162,.bashrc
3932165,.bash_logout
3932382,.zshrc
3932454,.gitconfig
3933234,.bash_aliases
3933512,.profile
3933612,.viminfo