Một giải pháp chung để chỉ xử lý các tệp không nhị phân khi bash
sử dụng file -b --mime-encoding
:
while IFS= read -d '' -r file; do
[[ "$(file -b --mime-encoding "$file")" = binary ]] &&
{ echo "Skipping $file."; continue; }
echo "Processing $file."
# ...
done < <(find . -type f -print0)
Tôi đã liên hệ với tác giả của tiện ích tệp và anh ta đã thêm một tham số tiện lợi -00
trong phiên bản 5.26 (phát hành 2016-04-16, ví dụ như trong Arch và Ubuntu 16.10 hiện tại) in ra file\0result\0
nhiều tệp được cung cấp cho nó cùng một lúc, bằng cách này bạn có thể làm ví dụ:
find . -type f -exec file -00 --mime-encoding {} + |
awk 'BEGIN{ORS=RS="\0"}{if(NR%2)f=$0;else if(!/binary/)print f}' | …
(Phần awk
này là để lọc ra mọi tệp không phải là nhị phân. ORS
Là dấu tách đầu ra.)
Cũng có thể được sử dụng trong một vòng lặp của khóa học:
while IFS= read -d '' -r file; do
echo "Processing $file."
# ...
done < <(find . -type f -exec file -00 --mime-encoding {} + |
awk 'BEGIN{ORS=RS="\0"}{if(NR%2)f=$0;else if(!/binary/)print f}')
Dựa trên điều này và trước đó tôi đã tạo ra một bash
tập lệnh nhỏ để lọc các tệp nhị phân sử dụng phương thức mới bằng cách sử dụng -00
tham số file
trong các phiên bản mới hơn của nó và quay lại phương thức trước đó trên các phiên bản cũ hơn:
#!/bin/bash
# Expects files as arguments and returns the ones that do
# not appear to be binary files as a zero-separated list.
#
# USAGE:
# filter_binary_files.sh [FILES...]
#
# EXAMPLE:
# find . -type f -mtime +5 -exec ./filter_binary_files.sh {} + | xargs -0 ...
#
[[ $# -eq 0 ]] && exit
if [[ "$(file -v)" =~ file-([1-9][0-9]|[6-9]|5\.([3-9][0-9]|2[6-9])) ]]; then
file -00 --mime-encoding -- "$@" |
awk 'BEGIN{ORS=RS="\0"}{if(NR%2)f=$0;else if(!/binary/)print f}'
else
for f do
[[ "$(file -b --mime-encoding -- "$f")" != binary ]] &&
printf '%s\0' "$f"
done
fi
Hoặc ở đây một POSIX-y hơn, nhưng nó yêu cầu hỗ trợ cho sort -V
:
#!/bin/sh
# Expects files as arguments and returns the ones that do
# not appear to be binary files as a zero-separated list.
#
# USAGE:
# filter_binary_files.sh [FILES...]
#
# EXAMPLE:
# find . -type f -mtime +5 -exec ./filter_binary_files.sh {} + | xargs -0 ...
#
[ $# -eq 0 ] && exit
if [ "$(printf '%s\n' 'file-5.26' "$(file -v | head -1)" | sort -V)" = \
'file-5.26' ]; then
file -00 --mime-encoding -- "$@" |
awk 'BEGIN{ORS=RS="\0"}{if(NR%2)f=$0;else if(!/binary/)print f}'
else
for f do
[ "$(file -b --mime-encoding -- "$f")" != binary ] &&
printf '%s\0' "$f"
done
fi
file
tiện ích ở đâu đó trong tập lệnh / đường ống của mình để xác định xem tệp là dữ liệu hay văn bản