按关键字组分隔文件列表,然后按反向日期对每个组进行排序

时间:2016-02-02 16:18:34

标签: bash sh ls

我用这个:

public class MyActivity extends Activity implements OnTouchListener {
Button mGreen, mRed;

void initialization() {

    ... //do initialization stuff

    mGreen.setOnTouchListener(this);
    mRed.setOnTouchListener(this);
}

@Override
public boolean onTouch(View v, MotionEvent event) {


    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            actionDown();
            break;
        case MotionEvent.ACTION_UP:
            actionUp();
            break;

        case MotionEvent.ACTION_POINTER_DOWN:
            break;

        case MotionEvent.ACTION_POINTER_UP:
            break;

        case MotionEvent.ACTION_MOVE:
            actionMove();
            break;
    }

    return true;
}

public void actionDown() {
    switch (view.getId()) {
        case R.id.button_green:
            //todo
            break;

        case R.id.button_red:
            //todo
            break;
    }
}

public void actionUp() {
    switch (view.getId()) {
        case R.id.button_green:
            //todo
            break;


        case R.id.button_red:
            //todo
            break;
    }
}

public void actionMove() {
    switch (view.getId()) {
        case R.id.button_green:
            // todo
            break;

        case R.id.button_red:
            // todo
            break;
    }

}}

...循环播放文件列表,从最旧到最新排序。

我想添加另一种排序"过滤":不以#34; abc"开头的文件名无论他们的时间戳如何,他们都是第一位的。

因此,如果文件是" abc.txt"," def.txt"和" ghi.txt",然后" abc.txt"必须是最后一个,其他两个在列表之前(按反向日期排序)。

2 个答案:

答案 0 :(得分:0)

文件:

ls -log
total 12
-rw-rw-r-- 1 4 Apr  8 11:15 abc.txt
-rw-rw-r-- 1 4 Apr  8 11:15 def.txt
-rw-rw-r-- 1 4 Apr  8 11:16 ghi.txt

这似乎有效,但必须有更好的方法:

ls -log --time-style +%s | tail -n +2 | \
pee \
    'grep -v abc.txt | sort -k4 -rn' \
    'grep    abc.txt | sort -k4 -rn' | \
cut -d " " -f 5

输出:

ghi.txt
def.txt
abc.txt

注意:名不见经传的util pee 来自 debian moreutils 包,它是' sa&#34 ;喜欢管道的 tee "。

现在制作一个循环:

# usage: foo filename   # filter above sort code by filename
foo() { ls -log --time-style +%s | tail -n +2 | \
        pee 'grep -v '"$1"' | sort -k4 -rn' \
            'grep '"$1"' | sort -k4 -rn' | \
        cut -d " " -f 5 ; }


for f in $( foo abc.txt )

答案 1 :(得分:0)

您不想解析ls命令的输出。您的问题中的结构是经典的bash pitfall,而parsing ls众所周知是有问题的。

您可以使用stat来获取在模式扩展的for循环中找到的每个文件的时间。

#!/usr/bin/env bash

uname_s=$(uname -s)

stamp() {
    case "$uname_s" in
        Linux)       stat -c '%Y' "$1" ;;
        Darwin|*BSD) stat -f '%m' "$1" ;;
    esac
}

inputfiles=( "$@" )

for file in "${inputfiles[@]}"; do
    n=$(stamp "$file")
    while [ -n "${forward[$n]}" ]; do
        ((n++))       # introduce fudge to avoid timestamp collissions
    done
    forward[$n]="$file"
done

declare -p inputfiles

for n in "${!forward[@]}"; do
        reverse[$(( 2**32 - $n ))]="${forward[$n]}"
done

declare -p forward reverse

此示例脚本将文件列表作为命令行选项(可以是glob),然后使用declare -p向您显示原始列表,转发排序列表和反向排序列表。

case函数中的stamp语句使其可以在Linux,OS X(Darwin),FreeBSD,NetBSD等之间移植,因为我不知道您正在使用什么操作系统。 (如果它不像Solaris,HP / UX等那么常见,那么stat命令可能不可用或无用,此解决方案可能无效。)

在bash中有一个排序(非关联)数组后,您可以使用以下结构逐个处理这些文件:

for file in "${forward[@]}"; do
    # something to $file
done

for file in "${reverse[@]}"; do
    # something to $file
done

你可以相信,由于非关联的bash数组总是按数字排序,你将按日期顺序获取文件。

当然,如果你愿意,你可以将日期作为索引。 :)