如何从ls输出动态排除文件?

时间:2019-01-07 17:26:09

标签: bash ls

我执行命令:

echo $(ls -p "/root/arch" -1tr | grep -v / )
20190107224626.ogg 20190107224705.ogg 20190107224720.ogg 20190107224645.ogg

我得到了文件的完整列表,从最旧的(从创建日期开始)排序。 一切正常。

还必须对文件进行动态排除(有些文件具有相同的名称,但扩展名.lock且位于不同的文件夹中):

echo $(ls -p "/root/pids" -1tr | grep -v / )
20190107224645.ogg.lock 20190107224705.ogg.lock

我执行命令:

echo $(ls -1tr /root/pids/*.lock | awk -F/ '{print $NF}' | grep -Po '.*(?=\.)' | while IFS= read -r line; do echo "-I \"$line\" "; done)
-I "20190107224645.ogg" -I "20190107224705.ogg"

现在,我尝试将所有这些都合并为一行,但是它并不能正常工作(我得到了全部4个文件,而不是2个),我在做什么错了,我该如何解决?

echo $(ls -p "/root/arch" -1tr $(ls -1tr /root/pids/*.lock | awk -F/ '{print $NF}' | grep -Po '.*(?=\.)' | while IFS= read -r line; do echo "-I \"$line\" "; done) | grep -v / )
20190107224626.ogg 20190107224705.ogg 20190107224720.ogg 20190107224645.ogg

3 个答案:

答案 0 :(得分:0)

如果我在短时间内阅读了标记为的问题后了解到一件事,那就是解析ls的输出是令人讨厌的。

下面是一种替代方法。遍历arch/中的每个文件,如果在.lock中找不到后缀为pids/的相应文件名,则输出文件名:

find arch -type f -printf '%f\0' | while IFS= read -r -d '' line; do
    if [[ ! -e pids/$line.lock ]]; then
      echo "$line"
    fi
done | sort -n

结果:

20190107224626.ogg
20190107224720.ogg

答案 1 :(得分:0)

使用流操作来完成此操作相对简单:

ls -p /root/{arch,pids} | grep -v / | sed 's/\.lock//g' | sort | uniq -u | xargs -l

答案 2 :(得分:0)

如果我对您的理解正确-

echo $(
  for f in /root/arch/*               # get each item
  do n="${f##*/}"                     # strip path
     [[ -e "/root/pids/$n.lock" ]] || # if there's NO matching lock
         printf "%s\n" "$n"           # then print the stripped filename
  done | sort -n                      # through a numeric sort
)                                     # to be stacked on one line by echo

那是什么东西吗?