
現在、次のコマンドがあり、各ファイル名をそれぞれの行に正常に印刷します。
find . -exec echo {} \;
find
コマンドが関数を実行するようにロジックを分割しようとしています。この質問私はこれを試しました:
my_function() {
echo $1
}
export -f my_function
find . -exec bash -c 'my_function "$@"' bash {} +
すると、次の出力が得られます。
.
$@
に置き換えてみることも試しましたが、改行のないすべてのファイルが対象になります。各ファイルをチェックするロジックを実行したいので、$*
一度に 1 つのファイルだけにしたいと思います。 で出力をスペースで分割しようとしましたが、ファイル名にスペースがあるファイルでは機能しません。 コマンドで見つかったすべてのファイルに対して Bash 関数を実行するにはどうすればよいですか?$1
$1
for file in $1
find
編集: 私が使用しているスクリプト全体は次のとおりです。問題なく動作するようです。
# Ensures that non-csproj text files are formatted with LF line endings.
format() {
for pathname do
if [[ $pathname == *"git"* ]]; then
continue
elif [[ $pathname == *"csproj"* ]]; then
continue
fi
dos2unix $pathname
done
}
export -f format
find . -exec bash -c 'format "$@"' bash {} \;
答え1
現在のディレクトリ内およびディレクトリ以下のすべての通常ファイルに対して実行しdos2unix --newline
、名前に文字列が含まれるファイルは避けますgit
。
find . -type f ! -name '*git*' -exec dos2unix --newline {} +
つまり、名前がパターン に一致しないすべての通常ファイルを検索し*git*
、dos2unix --newline
これらすべてに対して一度に可能な限り大きなバッチを実行します。パス名に文字列が含まれるファイル(ディレクトリ内のファイルなど)を回避するには! -name '*git*'
、 を変更します。! -path '*git*'
git
.git
ディレクトリを明示的に回避し、名前に含ま.git
れる可能性のある他のものをすべて含めるには、次のようにします。git
find . -name .git -prune -o -type f -exec dos2unix --newline {} +
これにより、検索ツリーからそのようなパスを削除するために、 によってfind
呼び出されるディレクトリへの入力も停止されます。.git
-prune
質問を編集する前の回答:
関数は最初の引数のみを出力します。ドットは、 で使用する最上位の検索パスですfind
。ディレクトリ エントリに対して特別なフィルタリングを行わないため、ドットは渡されます (たとえば、-type f
通常のファイルのみの場合、または 、-name
またはその他の種類のfind
テストの場合など)。
関数の各引数を出力したい場合は、次のいずれかを使用します。
my_function() {
printf '%s\n' "$@"
}
これにより、printf
各引数を改行文字を挟んで印刷することができます。
my_function() {
for pathname do
printf '%s\n' "$pathname"
done
}
引数をループし、printf
それぞれを 1 回呼び出します。
次のように関数を呼び出すと、正しく動作するはずです。
my_function "$@"
インラインbash -c
スクリプト内から。"$@"
スクリプトに渡されたすべての引数を個別に引用符で囲んで展開します。
別の方法としては、ループをbash -c
スクリプト内に移動することです。
for pathname do
my_function "$pathname"
done
そして
my_function () {
printf '%s\n' "$1"
}
これは、実行したいことを明示的に実行することになります。つまり、パス名ごとに関数を 1 回呼び出します。
コマンドはfind
次のようになります
find . -exec bash -c 'for pathname do my_function "$pathname"; done' bash {} +
あるいは、もう少し読みやすいかもしれないが、
find . -exec bash -c '
for pathname do
my_function "$pathname"
done' bash {} +
ちなみに、これは
shopt -s globstar nullglob dotglob
for pathname in ./**/*; do
my_function "$pathname"
done
ただし、.
処理されません。これを使用すると、関数をエクスポートする必要がなくなりますmy_function
。
関数内のループ(この回答の最初の2つのコードのように)を使用すると、これは次のように短縮されます。
shopt -s globstar nullglob dotglob
my_function ./**/*