2つの変数を下線で連結する


54

2つの変数を連結して、アンダースコアを持つファイル名を作成する必要があります。変数$FILENAMEを呼び出して$EXTENSION、ファイルからファイル名を読み取ることができます。

FILENAME=Hello
EXTENSION=WORLD.txt

今...

私は次のことを試みましたが成功しませんでした:

NAME=${FILENAME}_$EXTENSION
NAME=${FILENAME}'_'$EXTENSION
NAME=$FILENAME\\_$EXTENSION

私はいつも何らかの奇妙な出力を取得します。通常、最初にアンダースコアが使用されます。

私はそれが必要です

echo $NAME
Hello_WORLD.txt

2
おそらくスクリプトに復帰文字が含まれています。
ステファンシャゼル

はい、そうでした。:D-
リューク

回答:


67

次のようなものを使用できます。

NAME=$(echo ${FILENAME}_${EXTENSION})

これも機能します:

NAME=${FILENAME}_${EXTENSION}

1
問題は、NAMEの読み取り元のファイルでした。Windowsのフォーマット...その後、ソリューションはうまく機能しました。ありがとう
リューク

2
最初のコマンドは、変数の値とコマンド置換の使用をマングルし、echoおそらく助けにはなりません。2番目のコマンドは既に質問で指定されています。
ジル 'SO-悪であるのをやめる'

1
はい!大好きです。これは長い間私をいらいらさせていました。解決策をありがとう!
racl101

これは私のために動作します。「$ FILENAME_ $ EXTENSION」を使用すると、「$ EXTENSION」の値のみが表示されます。これがなぜ起こるのか説明してもらえますか?おかげで
レイハオ

12

きみの:

NAME=${FILENAME}_$EXTENSION
NAME=${FILENAME}'_'$EXTENSION

すべて大丈夫ですので:

NAME=${FILENAME}_${EXTENSION}
NAME=$FILENAME'_'$EXTENSION
NAME=$FILENAME\_$EXTENSION
NAME=$FILENAME"_$EXTENSION"

(しかし、それが使用演算子として確かではありません )。NAME=$(echo ${FILENAME}_${EXTENSION})echosplit+glob

NAME=$FILENAME_$EXTENSION

以下と同じでした:

NAME=${FILENAME_}${EXTENSION}

as _\またはorに反')は変数名の有効な文字です。

問題は、LFではなくCRLFで区切られた行があったことです。つまり、これらの可変コンテンツはCR文字で終わっていました。

CR文字は、端末に書き込まれると、カーソルを行の先頭に移動するよう端末に指示します。そのHello<CR>_WORLD.TXT<CR>ため、端末に送信されると_WORLD.TXT(を上書きするHello)と表示されます。


1

${FILENAME}_${EXTENSION}上記の構文を使用するように切り替えました。

以前は、$()2つの変数をアンダースコアで連結する必要があるときに使用していました。たとえば$YYYYMMDD$()_$HHMMSS、YYYYMMDD_HHMMSS形式のタイムスタンプを含むファイル名を生成します。中央$()は何も返さず、2つの変数を分割します。

上記のメソッドといくつかのメソッドをtime使用して割り当てを測定していましたが、これを使用し$YYYYMMDD$()_$HHMMSSている古いサーバーですべて0ミリ秒を報告しました。パフォーマンスは問題ではないようです。


それは質問に答えません。そのための新しい質問を提起する必要があります。$()いくつかのシェルでサブシェルをフォークします(一部はそれを最適化します)。また、設計されていない何かのためにオペレーターをハイジャックしています。${x}_yあなたが望むものです。
ステファンシャゼラス

「質問に答えられない」とはどういう意味ですか?それは素晴らしい答えではありませんが、答えです。
スコット

あいまいさを取り除くために編集されました。
user208145

0

変数は小文字で使用する必要があります(ベストプラクティスです)。
そのため、FILENAMEとEXTENSIONの代わりにファイル名と拡張子を使用します

「ファイル名はファイルから読み取られる」と言うように、スクリプトは次のようになります。

read -r filename  <file.txt
extension=World.txt

そして、変数$ filenameと$ extensionの両方をアンダースコアで連結したいこと_
ここで提供する例(ただし、二重\はありません)は、ここで正しく機能します。

name=${filename}_$extension
name=${filename}'_'$extension
name=$filename\_$extension

他のいくつかのように:

name="${filename}"'_'"${extension}"
name="$filename"'_'"$extension"
name="${filename}_${extension}"

したがって、問題は変数がどのように結び付いているかではなく、変数の内容にあります。これを考えるのは理にかなっているようです:

read -r filename  <file.txt

\rWindowsファイルから読み取る場合、末尾のキャリッジリターンを読み取ります。

1つの簡単な解決策(ksh、bash、zshの場合)は、読み取り変数からすべての制御文字を削除することです。

filename=${filename//[[:cntrl:]]/}

これは、キャリッジリターンのある値でシミュレートできます。

$ filename=$'Hello\r'
$ echo "starting<$filename>end"
>endting<Hello                       ### note the return to the start of line.
$ echo "starting<${filename//[[:cntrl:]]/}>end"
starting<Hello>end

または、次の値を置き換えますfilename

$ filename="${filename//[[:cntrl:]]/}"
$ echo "start<$filename>end"
start<Hello>end

結論。

したがって、この:

name="${filename//[[:cntrl:]]/}_${extension//[[:cntrl:]]/}"

name他の変数に制御文字が含まれている場合でも、正しい値を取得します。



-2

また、これを使用することもできます。個別の変数をスペースで区切り、trを使用して連結してスペースを削除します。

TableNameToCreate="MyTable"
# concatenation work is done here 
$(echo "$TableNameToCreate _my_other_Info " | tr -d " ")

#Proof
echo "Var to create with var pasted as prefix to suffix
    $(echo "$TableNameToCreate _my_other_Info " | tr -d " ") 
. "

# create a new var
NewVar=$(echo "$TableNameToCreate _my_other_Info " | tr -d " ")

#proof
echo "$NewVar"

(1)この質問にはすでに十分な回答があります。(2)既存の変数に特殊文字が含まれている場合、あなたの答えはどうなりますか?
G-Manは「Reinstate Monica」と言います

これは、キャリッジリターンを含む変数の問題を解決しません。また、不要なスペースを削除します。
クサラナナンダ

@Kusalananda:実際、私が何かを見落としていない限り、これはキャリッジリターンをうまく処理します。スペースが唯一の問題です。
G-Manは「Reinstate Monica」と言います
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.