私はbashとコーディングの初心者ですのでご了承ください。ファイルリスト(> 1000)があり、それを別の形式に変換する必要があります。ただし、一度に40個のファイルに対してこのコマンドを実行する必要があります。
私が試したことは次のとおりです。
path=/home/dir1/dir2/dir3;
ls ${path} >> ${path}/LIST;
FILES=${path}/LIST;
xargs -n 40 <<$FILES | xargs commandname
答え1
問題はリストを読むことです。
FILES=${path}/LIST;
しなければならない
FILES=$(<"${path}/LIST")
しかし、
xargs
ファイルを直接読むこともできますxargs -a "${path}/LIST"
。xargs
まったく繰り返す必要はありません。- ファイル名変数は常に二重引用符で囲む必要があります!
- パスにスペースや改行文字が含まれていると、スクリプトに多くの問題が発生します。
- ファイルが見つからない場合は、引数なしでコマンドを実行できないように追加されました
-r
。xargs
それでも、
代わりに配列を使用する必要があります。
また、ファイル名の一部として改行文字に関連する問題を回避するため\0
に、区切り文字とを一緒に使用することに慣れることをお勧めします。xargs -0
shopt -s nullglob # avoid `*` as file if no files found in $path
path=/home/dir1/dir2/dir3
files=("${path}"/*)
printf '%s\0' "${files[@]}" | xargs -0 -r -n40 commandname
shopt -u nullglob
またはparallel
代わりに使用してくださいxargs
:
shopt -s nullglob
parallel -j1 -n40 commandname ::: /home/dir1/dir2/dir3/*
答え2
zsh
を変更するには...を使用してくださいbash
。
autoload zargs
zargs -rl40 -- /home/dir1/dir2/dir3/*(nN) -- commandname
(ソート順n
の場合、通常は番号付きnumericglobsort
ファイルに適しています。file10
後ろに file2
たとえば)とN
for(したがってnullglob
一致するかどうかについて文句を言わず、隠しファイルが見つからないか読み取れない場合は保持されます。)/home/dir1/dir2/dir3/*
/home/dir1/dir2/dir3
答え3
私はこのようなものがGNU拡張を使わなくても機能できると思います。
set -- # clear positional arguments
for file in /home/dir1/dir2/dir3/*
do
[ -e "$file" ] || continue
set -- "$@" "$file"
if [ "$#" -eq 40 ]
then
commandname "$@"
set --
fi
done
# in case the number of files is a number not divisible by 40
if [ "$#" -gt 0 ] && [ "$#" -lt 40 ]
then
commandname "$@"
fi
コマンドが何であるかはわかりませんが、次の関数を作成したとき
commandname()
{
printf 'received %d arguments\n' "$#"
printf 'listing received filenames\n'
counter=0
for par in "$@"
do
counter="$(( counter+1 ))"
printf 'argument number %d: %s' "$counter" "$par" | LC_ALL=POSIX tr -d '[:cntrl:]'
printf '\n'
done
}
私が知っている限り、受信したメッセージの適切な数を表示し、すべて正しくリストします。ここにリストされているほとんどのファイル名をテストしました。シェルスクリプトのファイル処理の堅牢性をテストする方法は?(53ファイル)。
また、隠されたファイル(ドットで始まるファイル)は見つかりませんが、OPに作成した内容も見つからないので大丈夫だと思います。一般ファイルのみが必要な-e "$file" ]
場合[ -f "$file" ]
。
答え4
find /home/dir1/dir2/dir3 -maxdepth 1 -print0 |
xargs -0 -n 40 -P 0 commandname
ファイル数が40の倍数ではない場合、commandname
プロセスの1つは40個のパラメーターで実行されません。