INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
Saya ingin menjalankan perintah kedua ( head -1
) hanya jika perintah pertama berhasil. Bagaimana cara meningkatkan perintah ini?
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
Saya ingin menjalankan perintah kedua ( head -1
) hanya jika perintah pertama berhasil. Bagaimana cara meningkatkan perintah ini?
Jawaban:
Coba ini:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
Melewati xargs
satu -r
bendera akan menyebabkan ia hanya menjalankan basename
jika membaca setidaknya satu item dari input standar ( head -1
).
head -1
akan berjalan tetapi Anda tidak akan melihat atau menangkap output apa pun darinya.
Juga, jika Anda tidak ingin pengguna melihat output kesalahan ls
, Anda dapat mengarahkan ulang ls
aliran stderr ke /dev/null
.
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`
Perhatikan juga bahwa saya menambahkan tanda kutip di sekitar $MY_DIR
. Dengan begitu, perintah tidak akan gagal jika $MY_DIR
berisi spasi.
Jika Anda menggunakan shell modern seperti bash, Anda harus menggunakan $( )
shell ambil alih-alih backticks. Anda juga harus mempertimbangkan mengubah gaya variabel Anda. Anda umumnya harus menghindari menggunakan nama variabel huruf besar semua dalam skrip. Gaya itu umumnya dicadangkan untuk variabel cadangan dan lingkungan.
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
berfungsi.
Dalam saluran pipa, semua perintah dimulai dan dijalankan secara bersamaan, bukan satu demi satu. Jadi, Anda perlu menyimpan output di suatu tempat.
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
Perhatikan bahwa ini mengasumsikan nama file tidak mengandung karakter baris baru. Menggunakan xargs
juga berarti masalah dengan karakter kosong, tanda kutip tunggal dan ganda dan garis miring terbalik. Meninggalkan variabel yang tidak dikutip akan berarti masalah dengan karakter spasi, tab dan karakter pengganti. Lupa --
berarti masalah dengan nama file yang dimulai dengan -
.
Untuk mendapatkan nama file dari file terlama dengan zsh
tanpa batasan karakter apa pun (juga menghindari masalah ukuran argumen terbatas pada perintah):
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
Jika tidak ada kecocokan, perintah itu akan gagal dan membatalkan skrip. Anda juga dapat melakukan:
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
Dalam hal ini first_file_name
array akan berisi 1 elemen jika ada kecocokan atau 0 jika tidak. Anda kemudian dapat melakukan:
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
Temukan file yang dimodifikasi terbaru dalam direktori:
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"
}
Pemakaian: latest [directory/path/ [.extension]]
Alih-alih memanggil basename
, gunakan ekspansi parameter.
in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}
Dalam direktori dengan konten ini:
foo.xml bar.xml baz.xml newest.xml
Isi variabel base_fn adalah: newest
Untuk menggunakan ini dengan benar untuk memenuhi tujuan permintaan Anda:
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: setelah meninjau pertanyaan, saya menyadari bahwa ls
perintah tersebut mencari file tertua di direktori. fungsi yang sama ini dapat diubah namanya menjadi oldest
dan memiliki [[ $file -ot $oldest ]] && oldest=$file
untuk mencapai efek yang sama. permintaan maaf untuk kebingungan
hal penting yang perlu diperhatikan adalah bahwa Anda benar-benar, dalam keadaan apa pun dalam umat manusia, tidak boleh mem-parsing keluaran ls. tidak pernah.
ls
pendekatan berbasis, jika ada symlink, waktu modifikasi target symlink akan dipertimbangkan (tambahkan -L
opsi ls
untuk mendapatkan perilaku yang sama di sana).
Saya pikir pilihan terbaik di sini adalah:
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
jika tidak ada file maka kode pengembalian ls adalah 2 tetapi jika menemukan beberapa file akan menjadi 0.
$?
terhadap 0
, Anda dapat melakukan ini: if ls -rf $MY_DIR/FILE.*.xml ; then
.
ls
tidak akan gagal.