背景:コマンドラインユーティリティのラッパーでAutomatorで作業しています。プログラムに渡す最初のファイルパスを除くすべてを削除できるように、単一のスペースで区切られた任意の数のファイルパスを単一の文字列から分離する方法が必要です。
入力文字列の例:
/Users/bobby/diddy dum/Ding.mp4 /Users/jimmy/gone mia/come back jimmy.mp3 ...
必要な出力:
/Users/bobby/diddy dum/Ding.mp4
問題の一部は、Automator側の柔軟性の欠如です。スペース(またはコンマ)で区切られたエスケープされていないPOSIXファイルパスを返すAutomatorアクションを使用しています。これは残念なことです。1。ファイル/フォルダ名にスペースもカンマも含まれないことを保証できません。2。MacOSXファイル名で許可されない文字は(私が知る限り):
だけです。ファイルパスを二重引用符または一重引用符、または山かっこで囲むことができるオプションがあります。プログラム自体は前述の入力文字列の引数を受け入れるため、パスを分離する方法が必要です。 sed
またはawk
でそれを行う方法を理解するのに十分な鋭い目がありません。
最初は、sed
を使用してすべての[space]/
を[newline]/
に置き換えてから、最初の行を除くすべてをトリミングすると思いましたが、名前がで終わるフォルダーの抜け穴が開いたままになります空間。カンマ区切り文字を使用すると、代わりにカンマだけで同じことが起こります。二重引用符または一重引用符でカプセル化すると、それらの文字を含むファイル名用に別のワームの缶を開くことになります。
これは私のAutomatorワークフローの関連部分です:
-更新-
かなり回りくどい方法で、私が望んでいたことを達成することができました。それはほとんどエレガントではありませんが、ここでは一般化されたコードが機能しています:
path="/Users/bobby/diddy dum/Ding.mp4 /Users/jimmy/gone mia/come back jimmy.mp3"
# using colon because it's an inadmissible Mac OS X
# filename character, perfect for separating
# also, unlike [space], multiple colons do not collapse
IFS=:
# replace all spaces with colons
colpath=$(echo "$path" | sed 's/ /:/g')
# place words from colon-ized file path into array
# e.g. three spaces -> three colons -> two empty words
j=1
for Word in $colpath
do
filearray[$j]="$Word"
j=$j+1
done
# reconstruct file path Word by Word
# after each addition, check file existence
# if non-existent, re-add lost [space] and continue until found
name=""
for seg in "${filearray[@]}"
do
name="$name$seg"
if [[ -f "$name" ]]
then
echo "$name"
break
fi
name="$name "
done
デフォルトのIFSは、スペース間の「空」を単語としてカウントせず、すべてを折りたたむため、このすべての問題が発生します。
このシェルコードは、有効なファイル(パス)名を形成するまで、入力のセグメントを連結します。
file = "" sep = "" for Word in $ path do file = "$ file $ sep $ Word" if [[-f "$ file"]] then break fi sep = "" done echo "first file: '$ file'"
これは、名前付きファイルがすでに存在していることを前提としています(スクリプトはそれらを「見る」ことができます。つまり、ファイルが含まれているディレクトリを検索できます)。名前に複数の連続したスペースが含まれている場合(例:「diddy dum
"はOKですが、" diddy dum
" ではありません)。