2017-02-15 22 views
0

у меня есть много каталогов:найти только первый файл из многих каталогов

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 

Но имя папки отсутствует.

Когда я имею в виду первый файл, это первый файл, возвращенный в алфавитном порядке внутри папки.

Спасибо.

+3

StackOverflow помогает людям исправить свой существующий код, любой код, он не должен быть идеальным. Вы чувствуете, что использовать 'find, head, awk' очень близко к хорошей идее. Поэтому добавьте код, и люди помогут вам его исправить. Кроме того, пока вы показываете свой необходимый результат, каково фактическое «правило», которое вы используете для «первого файла» в каталоге?Сначала отсортировано по имени или первый файл, созданный в каталоге (поскольку дата создания не сохраняется в файловой системе Unix). Обновите свой Q с помощью этой важной информации. Удачи. – shellter

+0

Кроме того, что вы подразумеваете под первым файлом? –

+0

pluse uno для добавления кода и предоставления нам информации о том, что вы имеете в виду о «первом файле». Удачи. – shellter

ответ

0

Вы можете сделать это с помощью цикла 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 

Просто цикл через каталоги, и образуют массив из Глоб и захватить первый:

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's, просто сортируйте массив arr в соответствии с вашим определением перед первым элементом.


Вы также можете сделать это с 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 

И вставить sort (или используйте gawk) для сортировки в качестве желанной

0

sort имеет уникальную возможность. Только каталог должен быть уникальным, поэтому используйте первое поле при сортировке -k1,1. Решение работает, когда список файлов уже отсортирован.

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

Вам нужно будет изменить команду sed когда поле даты может сопровождаться другой номер.