bashパーティションファイルのリストと各グループでコマンドを実行する

bashパーティションファイルのリストと各グループでコマンドを実行する

私は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まったく繰り返す必要はありません。
  • ファイル名変数は常に二重引用符で囲む必要があります!
  • パスにスペースや改行文字が含まれていると、スクリプトに多くの問題が発生します。
  • ファイルが見つからない場合は、引数なしでコマンドを実行できないように追加されました-rxargs

それでも、

解析されないls

代わりに配列を使用する必要があります。

また、ファイル名の一部として改行文字に関連する問題を回避するため\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たとえば)とNfor(したがって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個のパラメーターで実行されません。

関連情報