INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
Tôi muốn thực hiện lệnh thứ hai ( head -1
) chỉ khi lệnh đầu tiên thành công. Làm thế nào để tôi cải thiện lệnh này?
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
Tôi muốn thực hiện lệnh thứ hai ( head -1
) chỉ khi lệnh đầu tiên thành công. Làm thế nào để tôi cải thiện lệnh này?
Câu trả lời:
Thử đi:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
Đi qua xargs
những -r
lá cờ sẽ gây ra nó để chỉ chạy basename
nếu đọc ít nhất một mục từ đầu vào chuẩn ( head -1
).
head -1
sẽ chạy nhưng bạn sẽ không thấy hoặc nắm bắt bất kỳ đầu ra nào từ nó.
Ngoài ra, nếu bạn không muốn người dùng thấy bất kỳ đầu ra lỗi nào ls
, bạn có thể chuyển hướng ls
luồng stderr của mình sang /dev/null
.
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`
Cũng lưu ý rằng tôi đã thêm dấu ngoặc kép xung quanh $MY_DIR
. Bằng cách đó, lệnh sẽ không thất bại nếu $MY_DIR
chứa khoảng trắng.
Nếu bạn đang sử dụng trình bao hiện đại như bash, bạn nên sử dụng trình $( )
bao chụp thay vì backticks. Bạn cũng nên xem xét việc thay đổi phong cách của các biến của bạn. Nói chung, bạn nên tránh sử dụng tên biến toàn chữ hoa trong tập lệnh. Phong cách đó thường được dành riêng cho các biến môi trường và dành riêng.
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
công trình.
Trong một đường ống, tất cả các lệnh được bắt đầu và chạy đồng thời, không phải lần lượt từng lệnh. Vì vậy, bạn cần lưu trữ đầu ra ở đâu đó.
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
Lưu ý rằng nó giả sử tên tệp không chứa ký tự dòng mới. Sử dụng xargs
cũng có nghĩa là các vấn đề với các ký tự trống, dấu ngoặc đơn và dấu ngoặc kép và dấu gạch chéo ngược. Để các biến không được trích dẫn có nghĩa là các vấn đề với không gian, tab và ký tự đại diện. Quên --
có nghĩa là vấn đề với tên tệp bắt đầu bằng -
.
Để có được tên cơ sở của tệp cũ nhất zsh
mà không có bất kỳ hạn chế nào đối với các ký tự (cũng tránh vấn đề về kích thước giới hạn của các đối số đối với một lệnh):
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
Nếu không có kết quả khớp, lệnh đó sẽ thất bại và hủy bỏ tập lệnh. Bạn cũng có thể làm:
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
Trong trường hợp đó, first_file_name
mảng sẽ chứa 1 phần tử nếu có khớp hoặc 0 nếu không. Sau đó bạn có thể làm:
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
Tìm tập tin sửa đổi mới nhất trong một thư mục:
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"
}
Sử dụng: latest [directory/path/ [.extension]]
Thay vì gọi ra basename
, sử dụng mở rộng tham số.
in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}
Trong một thư mục có các nội dung này:
foo.xml bar.xml baz.xml newest.xml
Nội dung của biến base_fn sẽ là: newest
Để sử dụng đúng cách để phục vụ mục đích yêu cầu của bạn:
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: khi xem xét câu hỏi, tôi đã nhận ra rằng ls
lệnh trong câu hỏi đang tìm kiếm tệp cũ nhất trong một thư mục. chức năng tương tự này có thể được đổi tên thành oldest
và [[ $file -ot $oldest ]] && oldest=$file
thay vào đó để đạt được hiệu quả tương tự. xin lỗi vì sự nhầm lẫn
điều quan trọng cần lưu ý là bạn tuyệt đối, trong mọi trường hợp không bao giờ có trong nhân loại, không nên phân tích đầu ra của ls. không bao giờ.
ls
phương pháp dựa trên cơ sở, nếu có liên kết tượng trưng, thời gian sửa đổi mục tiêu của các liên kết tượng trưng sẽ được xem xét (thêm -L
tùy chọn ls
để có hành vi tương tự ở đó).
Tôi nghĩ rằng lựa chọn tốt nhất ở đây là:
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
nếu không có tệp thì mã trả về của ls là 2 nhưng nếu tìm thấy một số tệp sẽ là 0.
ls
sẽ không thất bại.