入力ファイル名の拡張子だけを返すスクリプトを書きたい。たとえば、textfile.txt
はtxt
を返す必要があります。
Linuxとbashは初めてで、私は基本的なスクリプトの書き方を学ぼうとしています。ありがとうございます!
コメント
- stackoverflow.com/questions/965053/
linux-4.2.3.tar.xz
ファイルの拡張子は何ですか> kernel.org ?システムで最も確実に利用できる/bin/bash
ファイルの拡張子は何ですか?ご覧のとおり、"ファイル拡張子"の概念はLinuxではかなり異質です。ドットの後の部分は、システムにとってほとんど意味がありません。それは、ユーザーがそのファイルに何を期待するかについての手がかりです。そして、その手がかりは嘘をついているかもしれませんし、間違っているかもしれません。
回答
シェル、たとえばbashには多くの文字列操作機能。そのうちの1つを使用すると、特定のパターンまでのすべてを削除できます。
${VAR##GLOB}
上記の構文では、変数$VAR
は、glob GLOB
の最初の一致まで。したがって、ファイルの拡張子を名前なしで印刷するには、次のようにします。
$ file="file.txt" $ echo ${file##*.} txt
これは、複数の「拡張子」も処理できることに注意してください。
$ file="file.new.txt" $ echo ${file##*.} txt
それを望まない場合は、代わりに1つの#
を使用します。これにより、最短の一致が削除されます。最長のもの:
$ echo ${file#*.} new.txt
これをディレクトリ内のすべてのファイルで実行するには、次のようにします。
$ ls file.avi file.pdf file.png file.txt $ for file in *; do echo "$file : ${file##*.}"; done file.avi : avi file.pdf : pdf file.png : png file.txt : txt
また、完全を期すために、${file%.*}
を使用して拡張子なしでファイル名を取得することもできます:
$ for file in *; do echo "$file : ${file##*.} : ${file%.*}"; done file.avi : avi : file file.pdf : pdf : file file.png : png : file file.txt : txt : file
コメント
- これはfoo / .git / barのようなものでは機能しません' / bazエコーtest.txtを実行できると思います| awk -F ' / ' ' {print $ NF} ' | awk -F '。' ' {print $ NF} '
- @PaulMどういう意味ですか?その'拡張子のないファイル、それから何が得られると思いますか?
- echo " / foo /var/.git/foo/bar.bz " | awk -F ' / ' ' {print $ NF} ' | awk -F '。' ' {print $ NF} ' == > > bz
- @PaulM
file="/foo/var/.git/foo/bar.bz"; echo "${file##*.}"
:bz
。 '問題は発生しません。
回答
パラメータ拡張の場合:
$ x="textfile.txt" $ echo ${x##*.} txt
${parameter##word}
パターンは、word
(ファイルの末尾を除くすべて)に一致する最大のプレフィックスを削除します。
回答
必要なことを実行できる非常に単純なbashスクリプトは、次のようになります。
#!/usr/bin/env bash echo "$1" | awk -F "." "{print $NF}"
スクリプトはscript.sh test.txt
、そしてそれが行うことは
-
$1
をstdoutに出力します。$1
は、スクリプトに指定された最初のパラメーターです。この場合はtest.txt
です。 -
echo
のstdout出力は、文字列を分割するawk
のstdinにパイプされます(test.txt
).
で、分割の最後の要素(この場合はtxt
)を出力します。
ちょっとしたコメントですが、これは「非常に簡単な作業です:
echo test.txt | awk -F "." "{print $NF}"
コメントなので、1つのライナーで実行できます。
-
$1
の前後に引用符を追加する必要があります。そうしないと、スペースなどを含むファイル名が壊れる危険があります。 - これは' foo / .git / bar / bazのようなものでは機能しませんechotest.txt | awk -F ' / ' ' {print $ NF} ' | awk -F '。' ' {print $ NF} '
回答
#!/bin/bash my_file=`basename "$1"` # get full file name as a script parameter and strip the path my_extension="${my_file##*.}" my_file="${my_file%.*}" # will return base file name before the extension echo "$my_file" echo "$my_extension"
実行:
./script.sh index.html
出力:
index html
回答
そのためには、考慮すべきいくつかの注意事項があります。
-
foo.d/bar
ファイルには拡張子がなく、iv id = “のfoo
ファイルではありません。 5dcf1af6e9 “>
拡張子。
.bashrc
には拡張子がないことも考慮してください.
および..
の特別なディレクトリファイルは、おそらく特別に扱われ、拡張子がないと見なされる必要があります。file.tar.gz
? gz
またはtar.gz
? holiday.picture.jpg
またはbash-4.4
はどうですか?foo.d/
?空またはd
?ここで、次のようにします:
#! /bin/sh - for file do case ${file##*/} in (?*.*) ext=${file##*.};; (*) ext=;; esac printf "%s\n" "$ext" done
コメント
- 優れた回答は、通常の警告や、特に関数としての便利なコードも処理します。