INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
İkinci komutu ( head -1
) yalnızca ilk komut başarılı olduğunda yürütmek istedim . Bu komutu nasıl geliştirebilirim?
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
İkinci komutu ( head -1
) yalnızca ilk komut başarılı olduğunda yürütmek istedim . Bu komutu nasıl geliştirebilirim?
Yanıtlar:
Bunu dene:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
Bayrağın iletilmesi xargs
, -r
yalnızca basename
standart girdiden ( head -1
) en az bir öğe okunduğunda çalışmasına neden olur .
head -1
yayınlanacak, ancak herhangi bir çıktı görmeyecek veya yakalamayacaksınız.
Ayrıca, kullanıcının herhangi bir hata çıktısı görmesini istemiyorsanız, 'stderr akışını' ls
adresine yönlendirebilirsiniz .ls
/dev/null
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`
Ayrıca, içine tırnak işaretleri eklediğimi unutmayın $MY_DIR
. Bu şekilde, $MY_DIR
boşluklar varsa komut başarısız olmaz .
Eğer bash gibi modern bir $( )
kabuk kullanıyorsanız, ters tırnaklar yerine bir yakalama kabuğu kullanmalısınız. Değişkenlerinizin stilini de değiştirmeyi düşünmelisiniz. Genellikle komut dosyalarında büyük harfli değişken adları kullanmaktan kaçınmalısınız. Bu stil genellikle ayrılmış ve çevresel değişkenler için ayrılmıştır.
input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)
ls -rt GLOB 2>/dev/null | head -n1 | xargs -r basename
çalışır.
Bir boru hattında, tüm komutlar birbiri ardına değil, aynı anda başlatılır ve çalıştırılır. Bu nedenle çıktıyı bir yerde saklamanız gerekir.
if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
first_file=$(printf '%s\n' "$ls_output" | head -n 1)
first_file_name=$(basename -- "$first_file")
fi
Dosya adlarının yeni satır karakterleri içermediğini varsaydığını unutmayın. Kullanmak xargs
, boş karakterler, tek ve çift tırnak işaretleri ve ters eğik çizgilerle ilgili sorunlar anlamına da gelir. Değişkenleri tırnaksız bırakmak boşluk, sekme ve joker karakterlerle ilgili sorunlar anlamına gelir. Unutmak --
, dosya adlarıyla başlayan sorunlar anlamına gelir -
.
zsh
Karakterler üzerinde bu kısıtlamalardan herhangi biri olmadan en eski dosyanın taban adını almak için (ayrıca bir komuta ilişkin argümanların sınırlı boyutunun sorununu da önler):
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
Eşleşme yoksa, bu komut başarısız olur ve komut dosyasını iptal eder. Ayrıca şunları da yapabilirsiniz:
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
Bu durumda first_file_name
dizi, bir eşleşme varsa 1 öğe veya yoksa 0 öğesi içerir. Daha sonra şunları yapabilirsiniz:
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
En son değiştirilen dosyayı bir dizinde bulun:
latest() {
local file path=${1:-.} ext=${2-} latest
for file in "${path%/}"/*"$ext"; do
[[ $file -nt $latest ]] && latest=$file
done
[[ $latest ]] && printf '%s\n' "$latest"
}
Kullanımı: latest [directory/path/ [.extension]]
Seslenmek yerine basename
parametre genişletmeyi kullanın.
in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}
Bu içeriğe sahip bir dizinde:
foo.xml bar.xml baz.xml newest.xml
Base_fn değişkeninin içeriği: newest
Bunu isteğinizin amacına uygun olarak kullanmak için:
check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
printf '%s\n' "No file found in $check_dir" >&2
fi
EDIT: sorunun gözden geçirilmesi üzerine, söz konusu ls
komut bir dizindeki en eski dosyayı aradığını fark ettim . aynı işlev yeniden adlandırılabilir oldest
ve [[ $file -ot $oldest ]] && oldest=$file
bunun yerine aynı etkiyi elde edebilir. herhangi bir karışıklık için özür dileriz.
dikkat edilmesi gereken önemli bir nokta, kesinlikle, hiçbir koşulda insanlık içinde, ls çıktısını ayrıştırmamalısınız. asla.
ls
Tabanlı yaklaşımların aksine , sembolik bağlantılar varsa, sembolik düğmelerin hedefindeki değişiklik süresinin dikkate alınacağına dikkat edin ( orada aynı davranışı elde etme -L
seçeneğini ekleyin ls
).
Burada en iyi seçenek olduğunu düşünüyorum:
ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
echo "Error!"
fi
dosya yoksa, ls dönüş kodu 2'dir, ancak bazı dosya bulursa 0 olacaktır.
$?
Against 0
, bunu yapabilirsiniz: if ls -rf $MY_DIR/FILE.*.xml ; then
.
ls
başarısız olmaz.