基本ファイル名の最後の3文字を抽出する最も短い方法(サフィックス減算)

基本ファイル名の最後の3文字を抽出する最も短い方法(サフィックス減算)

shスクリプトの変数をファイルのデフォルト名の最後の3文字に設定しようとしています(デフォルト名はパスがないことを意味します)。そしてサフィックスなし)。これはうまくいきましたが、純粋な好奇心として使用できる短い単一のコマンドがあるかどうかを知りたいです。もともとは一行でしたawkが、かなり長かったです。現在、次の2行のスクリプトがあります(フルファイル名があると仮定$1)。

filebase=`basename "$1"`
lastpart=`echo -n ${filebase%.*} | tail -c3`

例えば、"/パス/to/somefile.txt"最後に「エリー」存在する$lastpart

何とかビットを組み合わせて、basenameサフィックスを単一のコマンドで削除できますか?tailパイプを使わずにサフィックス(または利用可能な他の項目)に送信する方法はありますか?サフィックスがわからないため、パラメータとして渡すことはできませんbasename

実際、主な目標はできるだけ短く書くのではなく、できるだけ明確に書くことです。これらすべての実際の背景は次のとおりです。スーパーユーザーに関する質問です。、私は非常に簡単な答えをしようとしました。

ベストアンサー1

var=123456
echo "${var#"${var%???}"}"

###OUTPUT###

456

まず、最後の3文字を削除し、次に削除$var結果から最後の3文字を削除します。以下は、このようなタスクを実行する方法を示すために設計されたいくつかの具体的な例です。$var$var

touch file.txt
path=${PWD}/file.txt
echo "$path"

/tmp/file.txt

base=${path##*/}
exten=${base#"${base%???}"}
base=${base%."$exten"}
{ 
    echo "$base" 
    echo "$exten" 
    echo "${base}.${exten}" 
    echo "$path"
}

file
txt
file.txt
/tmp/file.txt

あまりにも多くのコマンドを使用してすべてを広げる必要はありません。次のように圧縮できます。

{
    base=${path##*/} exten= 
    printf %s\\n "${base%.*}" "${exten:=${base#"${base%???}"}}" "$base" "$path"
    echo "$exten"
}

file 
txt 
file.txt 
/tmp/file.txt
txt

$IFStingシェルパラメータと組み合わせると、setシェル変数を解析して掘削するための非常に効果的な手段になる可能性があります。

(IFS=. ; set -f; set -- ${path##*/}; printf %s "${1#"${1%???}"}")

/これにより、最後のピリオドの後に最初のピリオドの直前の3文字のみが表示されます$path.最後の文字より前の最初の3文字だけを検索したい場合$path .(例:ファイル名に複数がある場合):

(IFS=.; set -f; set -- ${path##*/}; ${3+shift $(($#-2))}; printf %s "${1#"${1%???}"}")

どちらの場合も、次のことができます。

newvar=$(IFS...)

そして…

(IFS...;printf %s "$2")

...次を印刷します.

外部プログラムを使用しても問題ない場合は、次のことができます。

printf %s "${path##*/}" | sed 's/.*\(...\)\..*/\1/'

\nファイル名に改行文字がある場合(ネイティブシェルソリューションでは動作しません - とにかく処理します):

printf %s "${path##*/}" | sed 'H;$!d;g;s/.*\(...\)\..*/\1/'

おすすめ記事