web-dev-qa-db-ja.com

長いパスからファイルのベース名を抽出するbash

bashでは、プログラムへの入力として提供するディレクトリからのファイルのリストをglobしようとしています。ただし、このプログラムにファイル名のリストも提供したいと思います

files="/very/long/path/to/various/files/*.file"

だから私はそれをそのように使うことができました。

Prompt> program -files $files -names $namelist

globが私にくれたら:

/very/long/path/to/various/files/AA.file /very/long/path/to/various/files/BB.file /very/long/path/to/various/files/CC.file /very/long/path/to/various/files/DD.file /very/long/path/to/various/files/ZZ.file

AA BB CC DD ZZのリストを取得して、長いパス名とファイル拡張子を付けずにプログラムをフィードします。しかし、私はそこからどのように始めるかについての手がかりはありません!どんなヒントでも大歓迎です!

12
Benoit B.

ファイル名を保持するには配列を使用することをお勧めします。文字列変数は、スペースを含むファイル名を処理しません。

また、basenameコマンドを使用する必要はありません。代わりに、bashの組み込みの文字列操作を使用してください。

これを試して:

files=( /very/long/path/to/various/files/*.file )
for file in "${files[@]}"
do
  filename="${file##*/}"
  filenameWithoutExtension="${filename%.*}"
  echo "$filenameWithoutExtension"
done
26
dogbane

あなたの質問に対するbasenameによる解決策

for file in $files
do
  file_name=$(basename $file)
  file_name_witout_ext=${file_name%.file}
done

編集((単一の)拡張子なしでファイル名を抽出する一般的な方法)

for file in $files
do
  file_name=$(basename $file)
  file_name_witout_ext=${file_name%.*}
done

起こり得るもう1つのことは、「archive.tar.gz」のようなファイル名を持つことです。この場合、2つ(または複数の拡張子)になります。その後、より厄介な演算子を使用できます

for file in $files
do
  file_name=$(basename $file)
  file_name_witout_ext=${file_name%%.*}
done
6
epsilon

次のように簡単です:

files=(/very/long/path/to/various/files/*.file)
names=("${files[@]##*/}") names=("${names[@]%.*}")
progname -files "${files[@]}" -names "${names[@]}"

または、それらを単一の引数としてのみ渡すことができる場合:

progname -files "${files[*]}" -names "${names[*]}"
3
konsolebox