Bash 只查找多个目录中的第一个文件
我有很多目录:Bash 只查找多个目录中的第一个文件,bash,unix,awk,command-line,find,Bash,Unix,Awk,Command Line,Find,我有很多目录: 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 2013
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
这是文件名中的目录名和日期。
我想我需要一个查找和头部命令+awk,但我做不到,我需要你的帮助
这是我的测试结果
for f in $(ls -1);do ls -1 $f/ | head -1;done
但是缺少文件夹名
当我指的是第一个文件时,是在文件夹中按字母顺序返回的第一个文件
谢谢。您可以通过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
如果您对“first”的定义与Bash的不同,那么在获取第一个元素之前,只需根据您的定义对数组进行排序
您还可以使用
find
和awk
执行此操作:
$ 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
然后插入一个
排序
(或使用gawk
)按需排序您可以使用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
如果您对“first”的定义与Bash的不同,那么在获取第一个元素之前,只需根据您的定义对数组进行排序
您还可以使用
find
和awk
执行此操作:
$ 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
并插入一个
排序
(或使用gawk
)按需排序排序
具有唯一选项。只有目录应该是唯一的,所以使用排序-k1,1
中的第一个字段。当文件列表已排序时,该解决方案有效
printf "%s\n" */* | sort -k1,1 -t/ -u | sed 's#\(.*\)/\([0-9]*\).*#\1|\2#'
当日期字段后面可能跟有另一个数字时,您需要更改
sed
命令。sort
具有唯一选项。只有目录应该是唯一的,所以使用排序-k1,1
中的第一个字段。当文件列表已排序时,该解决方案有效
printf "%s\n" */* | sort -k1,1 -t/ -u | sed 's#\(.*\)/\([0-9]*\).*#\1|\2#'
当日期字段后面可能跟有另一个数字时,您需要更改sed
命令。这对我很有用:
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
这对我很有用:
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
StackOverflow是帮助人们修复他们现有的代码,任何代码,都不一定是完美的。您感觉使用
查找、头部、awk
非常接近一个好主意。因此,添加一些代码,人们会帮助您修复它。另外,当您显示所需的输出时,您对目录中的“第一个文件”使用的实际“规则”是什么?按名称排序,或按目录中创建的第一个文件排序(因为创建日期不保留在Unix文件系统中)。请用关键信息更新你的Q。祝你好运。还有,你说的第一个文件到底是什么意思?加上一些代码,让我们知道你说的“第一个文件”是什么意思。祝你好运。StackOverflow是帮助人们修复他们现有的代码,任何代码,都不一定是完美的。您感觉使用查找、头部、awk
非常接近一个好主意。因此,添加一些代码,人们会帮助您修复它。另外,当您显示所需的输出时,您对目录中的“第一个文件”使用的实际“规则”是什么?按名称排序,或按目录中创建的第一个文件排序(因为创建日期不保留在Unix文件系统中)。请用关键信息更新你的Q。祝你好运。还有,你说的第一个文件到底是什么意思?加上一些代码,让我们知道你说的“第一个文件”是什么意思。祝你好运