【问题标题】:find only the first file from many directories从许多目录中只找到第一个文件
【发布时间】:2017-07-04 09:09:39
【问题描述】:

我有很多目录:

13R
613
AB1
ACT
AMB
ANI

每个目录都包含很多文件:

20140828.13R.file.csv.gz
20140829.13R.file.csv.gz
20140830.13R.file.csv.gz
20140831.13R.file.csv.gz
20140901.13R.file.csv.gz

20131114.613.file.csv.gz
20131115.613.file.csv.gz
20131116.613.file.csv.gz
20131117.613.file.csv.gz

20141114.ab1.file.csv.gz
20141115.ab1.file.csv.gz
20141116.ab1.file.csv.gz
20141117.ab1.file.csv.gz

etc..

从每个目录中获取第一个文件的目的

我期望的结果是:

13R|20140828
613|20131114
AB1|20141114

目录的名称是文件名中的日期。 我想我需要一个 find 和 head 命令 + awk 但我做不到,我需要你的帮助。

这是我测试过的

for f in $(ls -1);do ls -1 $f/ | head -1;done

但是文件夹名不见了。

当我指的是第一个文件时,是文件夹中按字母顺序返回的第一个文件。

谢谢。

【问题讨论】:

  • StackOverflow 是关于帮助人们修复他们现有的代码,任何代码,它不一定是完美的。你感觉使用find,head,awk 非常接近一个好主意。所以添加一些代码,人们会帮助你修复它。此外,当您显示所需的输出时,您对目录中的“第一个文件”使用的实际“规则”是什么?首先按名称排序,或在目录中创建的第一个文件(因为创建日期不保存在 Unix 文件系统中)。请使用该关键信息更新您的 Q。祝你好运。
  • 另外,第一个文件到底是什么意思?
  • 加上 uno 用于添加一些代码并让我们知道您对“第一个文件”的意思。祝你好运。

标签: bash unix awk command-line find


【解决方案1】:

您可以使用 Bash 循环来做到这一点。

给定:

/tmp/test
/tmp/test/dir_1
/tmp/test/dir_1/file_1
/tmp/test/dir_1/file_2
/tmp/test/dir_1/file_3
/tmp/test/dir_2
/tmp/test/dir_2/file_1
/tmp/test/dir_2/file_2
/tmp/test/dir_2/file_3
/tmp/test/dir_3
/tmp/test/dir_3/file_1
/tmp/test/dir_3/file_2
/tmp/test/dir_3/file_3
/tmp/test/file_1
/tmp/test/file_2
/tmp/test/file_3

只需遍历目录并从一个 glob 形成一个数组并获取第一个:

prefix="/tmp/test"
cd "$prefix"
for fn in dir_*; do 
    cd "$prefix"/"$fn"
    arr=(*)
    echo "$fn|${arr[0]}"
done

打印:

dir_1|file_1
dir_2|file_1
dir_3|file_1

如果您对“第一个”的定义与 Bash 的不同,只需根据您的定义对数组arr 进行排序,然后再获取第一个元素。


您也可以使用findawk 执行此操作:

$ find /tmp/test -mindepth 2 -print0 | awk -v RS="\0" '{s=$0; sub(/[^/]+$/,"",s); if (s in paths) next; paths[s]; print $0}'
/tmp/test/dir_1/file_1
/tmp/test/dir_2/file_1
/tmp/test/dir_3/file_1

并插入sort(或使用gawk)进行排序

【讨论】:

    【解决方案2】:

    sort 有一个独特的选项。只有目录应该是唯一的,所以在排序时使用第一个字段-k1,1。当文件列表已经排序时,该解决方案有效。

    printf "%s\n" */* | sort -k1,1 -t/ -u | sed 's#\(.*\)/\([0-9]*\).*#\1|\2#'
    

    当日期字段后面可能跟着另一个数字时,您需要更改sed 命令。

    【讨论】:

      【解决方案3】:

      这对我有用:

      for dir in $(find "$FOLDER" -type d); do
        FILE=$(ls -1 -p $dir | grep -v / | head -n1)
        if [ ! -z "$FILE" ]; then
          echo "$dir/$FILE"
        fi
      done
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-23
        • 2013-03-03
        • 2012-08-20
        • 1970-01-01
        • 2011-10-29
        • 1970-01-01
        • 2015-10-15
        • 1970-01-01
        相关资源
        最近更新 更多