sh / bashからインデックスとして文字列を参照する方法は?つまり、基本的に分かれています。
ファイル名から5文字を削除しようとしています。すべての名前の構造は name_nr_code です。英数字コードの5桁を削除しようとしています。name_nr_
常に10文字です。
似たようなものがありますか?
for i in * ; do mv "$i" "$i"[:10] ; done
答え1
とても簡単です。
(しゃっくり)
for i in * ; do mv -- "$i" "${i:0:5}" ; done
望むより。
そしての説明高度なバッシュスクリプトガイド(第10章 変数操作)、(追加のNOTEマニュアルのエラーを強調するためのインライン):
部分文字列の抽出
${string:position}
次の部分文字列を抽出します。
$string
存在する$position
。パラメータが「*」または「@」の場合、
$string
位置パラメータはから始まり抽出されます$position
。${string:position:length}
抜粋
$length
部分文字列の文字は次のようになります。$string
存在する$position
。
NOTEパラメータ拡張に引用符がありません! echo
任意のデータと一緒に使用しないでください。
stringZ=abcABC123ABCabc
# 0123456789.....
# 0-based indexing.
echo ${stringZ:0} # abcABC123ABCabc
echo ${stringZ:1} # bcABC123ABCabc
echo ${stringZ:7} # 23ABCabc
echo ${stringZ:7:3} # 23A
# Three characters of substring.
# Is it possible to index from the right end of the string?
echo ${stringZ:-4} # abcABC123ABCabc
# Defaults to full string, as in ${parameter:-default}.
# However . . .
echo ${stringZ:(-4)} # Cabc
echo ${stringZ: -4} # Cabc
# Now, it works.
# Parentheses or added space "escape" the position parameter.
これ場所そして長さパラメータは「パラメータ化」できます。つまり、数値定数ではなく変数として表示されます。
引数が「*」または「@」の場合、最初から
$string
最大位置引数が抽出されます。$length
$position
echo ${*:2} # Echoes second and following positional parameters.
echo ${@:2} # Same as above.
echo ${*:2:3} # Echoes three positional parameters, starting at second.
NOTE: はexpr substr
GNU 拡張です。
expr substr $string $position $length
抜粋
$length
の文字$string
次から始まった$position
。
stringZ=abcABC123ABCabc
# 123456789......
# 1-based indexing.
echo `expr substr $stringZ 1 2` # ab
echo `expr substr $stringZ 4 3` # ABC
NOTE:これはecho
冗長で信頼性がはるかに低いです。使用expr substr + "$string1" 1 2
。
NOTE:expr
出力が0(または-0、00 ...)の場合、ゼロ以外の終了ステータスが返されます。
ところで。この本は公式Ubuntuリポジトリからabs-guide
。
答え2
POSIXではsh
、
"${var%?????}"
$var
最後の5文字を削除します(または文字が5文字未満の$var
場合)。$var
"${var%"${var#??????????}"}"
はい、最初の10文字です$var
。"${var%_*}"
$var
(->)末尾から一致する最も短い文字列を削除します。_*
$var
foo_bar_baz
foo_bar
"${var%%_*}"
:同じですが、最も短い一致(foo_bar_baz
->foo
)ではなく、最も長い一致です。- 以下を取得したい場合
foo_bar_
:("${var%"${var##*_}"}"
終わりの代わりに始めからパターンを見つけるのと同じ${var##pattern}
)。${var%%pattern}
$var
そしてzsh
:
$var[1,-6]
最初の文字から6番目の文字から最後の文字まで(最後の5文字を除くすべての文字)$var[1,10]
最初の10文字。
ksh
、またはbash
:zsh
"${var:0:10}"
:の最初の10文字$var
またはbash
:zsh
"${var:0:-5}"
$var
:最後の5文字を除くすべての文字(設定されているが5文字未満の場合はエラーを表示してスクリプトを終了します。useなしで$var
設定した場合も同様ですzsh
)。
Bourneの互換性が必要な場合、sh
安定して実行するのは難しいです。結果が改行で終わらないことを保証できる場合は、次のことができます。
first_10=`expr " $var" : ' \(.{1,10\}\)'` # beware the exit status
# may be non-zero if the
# result is 0 or 0000000000
all_but_last_5=`expr " $var" : ' \(.*\).\{5\}'`
また、長さ制限が適用されます$var
(システムによって異なります)。
これらすべてのソリューションで$var
有効な文字の一部を構成できないバイトを含めると、YMMVになります。
答え3
sh
(私が知っている限り)文字列から部分文字列を取得する組み込みの方法はありませんが、bash
次のことができます。
${i:0:10}
これにより、変数valueの最初の10文字が提供されますi
。
一般的な形式は${variable:offset:length}
。
答え4
for
まず、ファイル名にループを使用しないでください。
まあ、このようなものが役に立ちます。
find ./ -type f | while read filename ;do
newfilename=$(echo ${filename}|cut -c 1-10)
mv ${filename} ${newfilename}
done