2017-03-10 26 views
5

Bash için "Extended pattern" extglob'a rastladım. Ben sadece yazabilirsiniz dizinde 2017/02/27 ve 2017/02/28 dosyaları listelemek istersenizBash genişletilmiş desende kaçış @ (..)

/basedir/2017/02/26/uniquedirs1/files.log 
/basedir/2017/02/27/uniquedirs2/files.log 
/basedir/2017/02/28/uniquedirs3/files.log 
/basedir/2017/03/01/uniquedirs4/files.log 
/basedir/2017/03/02/uniquedirs5/files.log 

:

Böyle bir dizin yapısını düşünün: http://wiki.bash-hackers.org/syntax/pattern

Bu davayı araştırıyorum:

ls /basedir/2017/02/@("27"|"28")/*/files.log 

Awesome! Şimdi bu soruya cevap verin. Bash genişletilmiş modelinde birden fazla dizini nasıl tanımlayabilirim?
Bu işe yaramazsa:

ls /basedir/2017/@("02/28"|"03/01")/*/files.log 
ls /basedir/2017/@("02\/28"|"03\/01")/*/files.log 

ben "Genişletilmiş desen" için birden fazla dizin tanımlamak için olsun herhangi bir yolu var mı?

cevap

4

Yol adı oluşturma yalnızca yol adı bileşenlerine desen uygular; Bileşenleri ayıran / ile asla eşleşmezler. Ayraç genişleme temizleyici burada olacaktır:

ls /basedir/2017/{2/28,3/01}/*/files.log 

ilk iki sonuçlanan modellerine yol adı nesil gerçekleştirmeden önce

ls /basedir/2017/2/28/*/files.log /basedir/2017/3/01/*/files.log 

kadar genişleyip hangi.

+0

Brace genişletme ile ilgili tek sorun, aralığı dinamik olarak tanımlayamamam. – Asgair

+1

Uzun desenlerle yapamazsınız, yani bir şey kaybetmezsiniz :) – chepner

+0

Tamam. Bu utanç verici ... Hala verimli bir çözüme daha yakın değilim. Sahip olduğum tek sorun, bir brace genişlemesinin dinamik olarak tanımlanamamasıdır. Bir alt kabukta yürütmediğim sürece, var1 = "02/28,03/01" ls/basedir/2017/"$ var1"/*/files.log' gibi. Ama bu çalışır: 'var2 =" 27 | 28 "ls/basedir/2017/02/@ (" $ var2 ")/*/files.log' – Asgair

0

Tamam, ben dinamik olarak bu çözdük yolu, şu şekildedir: Eğer dosyayı kullanamıyorsanız grep veri getirmek için gibi araçlarla kullanmak istiyorsanız

#!/bin/bash 
# User input: 
start_date="2017-02-27" 
day_range=2 

# Logic: 

declare -a 'date_range=($(echo {'"$day_range"'..0} | xargs -I{} -d " " date -d "'"$start_date"' +{} day" --rfc-3339="date"))' 
#this creates an array with dates: 
#2017-03-02 2017-03-01 2017-02-28 2017-02-27 

eval ls "basedir/{$(IFS=\, ; echo "${date_range[*]//-//}")}/*/files.log" 
#this translates to: 
#ls basedir/{2017/03/01,2017/02/28,2017/02/27}/*/files.log 

Bu daha yararlıdır -Creation-kalmadır.