web-dev-qa-db-ja.com

シェルスクリプトの引数リストから最後の引数を削除します(bash)

この質問は、オートマトンosxで実行されるbashスクリプトに関するものです。 Finderから一連のファイル参照を取得してフィルタリングするために、オートマトンアクションを使用しています。次に、オートマターアクションを使用して、そのリストに親フォルダーの名前を追加します。次に、Automatorはこれらの引数を「シェルスクリプトの実行」と呼ばれるアクションにフィードします。 automatorがスクリプトを呼び出す方法は正確にはわかりませんが、次のようにエコーすると、引数リストは次のようになります。echo "$@"

/ Volumes/G-Raid/Online/WAV_TEST/Testbok 50/01/01000 43-001.wav/Volumes/G-Raid/Online/WAV_TEST/Testbok 50/02/02000 43-002.wav/Volumes/G-Raid/Online/WAV_TEST/Testbok 50/03/03000 43-003.wav/Volumes/G-Raid/Online/WAV_TEST/Testbok 50

この場合、3つのファイルと1つのフォルダーへのパス。

シェルスクリプトでは、オートマターから渡された引数からリストの最後の引数(フォルダー)を引いた状態で、ripcheckc *というアプリケーションを起動します。

私はこれを使用して最後の引数を削除します:

_args=( "$@" )
unset _args[${#_args[@]}-1]

そしてこれはecho $_argsです:

/ Volumes/G-Raid/Online/WAV_TEST/Testbok 50/01/01000 43-001.wav/Volumes/G-Raid/Online/WAV_TEST/Testbok 50/02/02000 43-002.wav/Volumes/G-Raid/Online/WAV_TEST/Testbok 50/03/03000 43-003.wav

以前と同じですが、フォルダはありません。

ここで、引数として"$@"を指定してripcheckcを実行すると機能します(ただし、引数リストの最後のパスのために後で失敗します)${_args[@]}を使用すると、アプリケーションはサイレントに中止されます。 $@_argsをエコーすると、最後の引数を除いて出力は同じに見えます。

私の質問は、最初の有効な入力と2番目の入力を行わない$ @と$ _argsの違いは何ですか?

*アプリケーションは ripcheckc

私の質問が理にかなっていることを願っています。

編集:解決しました。

19
Nordanfors

すでにarrayがあるとすると、次のように言うことができます。

unset "array[${#array[@]}-1]"

たとえば、スクリプトに次のものが含まれている場合:

array=( "$@" )
unset "array[${#array[@]}-1]"    # Removes last element -- also see: help unset
for i in "${array[@]}"; do
  echo "$i"
done

で呼び出す:bash scriptname foo bar baz生成:

foo
bar
8
devnull

私は以前にこのbashワンライナーを使用しました

_set -- "${@:1:$(($#-1))}"
_

引数リストを、最後の引数を差し引いた現在の引数リストに設定します。


使い方:

  • _$#_は引数の数です
  • $((...))は算術式であるため、$(($#-1))は引数の数より1つ少なくなります。
  • _${variable:position:count}_は 部分文字列式 :位置から始まるcountからvariable文字を抽出します。 特別な場合 ここでvariableは_@_であり、これは引数リストを意味し、countargumentspositionで始まるリストから。ここで、positionは最初の引数の_1_であり、countは以前に処理された引数の数より1つ少ない数です。
  • _set -- arg1...argn_ 引数リストを設定します 指定された引数に

したがって、最終的な結果として、引数リストが新しいリストに置き換えられます。新しいリストは、最後の引数を除いて元のリストです。

30
starfry

最後の引数以外のすべてをで取得することもできます

"${@:0:$#}"

正直なところ、これは少し大雑把です。引数が0ではなく1から始まるという事実を(ab)使用しているように見えるからです。

更新:これは、$@の処理におけるバグ(遅くとも4.1.2で修正)が原因でのみ機能します。バージョン3.2で動作します。

10
chepner