bashで文字列にインデックスを付ける


14

sh / bashのインデックスで文字列を参照するにはどうすればよいですか?つまり、基本的にそれを分割します。

ファイル名の5文字を​​削除しようとしています。すべての名前の構造は、name_nr_codeです。5つの英数字コードビットを削除しようとしています。name_nr_常に10文字です。

ようなものがあります;

for i in * ; do mv "$i" "$i"[:10] ; done


5
解決策をbash求めているのにタグが必要なのはなぜshですか?
ステファンシャゼラス

回答:


14

このようにシンプル。

(bash)

for i in * ; do mv -- "$i" "${i:0:5}" ; done

出来上がり。

Advanced Bash-Scripting Guide第10章変数の操作からの説明(NOTEそのマニュアルのエラーを強調するためのインラインs を追加):

部分文字列の抽出

${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.

NOTEexpr 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ます。

NOTEexpr出力が0(または-0、00 ...)の場合、ゼロ以外の終了ステータスで戻ります。


ところで。この本は、Ubuntuの公式リポジトリにとして存在していますabs-guide


「位置」は実際にはオフセットであるため、少し誤解を招く可能性があります。つまり、「1番目の位置」からではなく、実際には2番目からの${var:1}値を返しますvar
クサラナンダ

それは事実ですが、あなたが同意しない限り、ゼロ番目の位置が存在する可能性があります。私はそれでいいです。

9

POSIXではsh

  • "${var%?????}"され$var、最後の5つの末尾の文字を剥奪(または$var場合は$var5文字未満含まれています)

  • "${var%"${var#??????????}"}"はの最初の10文字です$var

  • "${var%_*}"(-> )の末尾で$var一致する最短文字列が削除されます。_*$varfoo_bar_bazfoo_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文字。

あるいは:kshbashzsh

  • "${var:0:10}":最初の10文字 $var

bashzsh

  • "${var:0:-5}":最後の5文字を​​除くすべて($var設定されている場合にエラーが発生し、スクリプトが終了しますが、5文字未満の場合、また$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。


私、彼らは本当にそれらの中括弧のためにいくつかのreallyい構文を思いつきました。

2

sh文字列から部分文字列を取得する組み込みの方法を提供していません(私が見る限り)が、bashあなたと一緒に行うことができます

${i:0:10}

これにより、変数の値の最初の10文字が得られますi

一般的な形式は${variable:offset:length}です。


2

ほとんどのシェルは、あなたを助けることができるある種のパラメータ拡張をサポートしています。bashでは、次を使用できます

substr=${string:4:5} # start at position 4, length 5.

ではdash、オフセットはサポートされていませんが、先頭と末尾のパターンを使用できます。

remove_first3=${string#???}
remove_last2=${string%??}

0

まずfor、ファイル名にループを使用しないでください。

次に、このような何かが役立つはずです。

find ./ -type f | while read filename ;do
  newfilename=$(echo ${filename}|cut -c 1-10)
  mv ${filename} ${newfilename}
done

3
forファイル名で使用するのが悪いのはなぜですか?
チョロバ

変数を引用して、printfより安全にするために使用します。...およびread -r
クサラナナンダ

3
OPのforループは多分行方不明を除いて大丈夫だった--。4行のコードに少なくとも10個のバグがあります。単一行、使用エコー、不足している引用符のファイル名をしていると仮定のようなよく知られた悪い習慣その多く
ステファンChazelas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.