
この問題を解決するために助けが必要です。名前のリストを含むファイルがあります:
名前.txt
roger
peter
henry
:
名前の後に連結したい
for i in $(cat names.txt); do
$i+=$i":"
done
私が望む出力はこれですroger:peter:henry
しかし、この出力が得られましたroger:peter:henry:
答え1
それをあなたに代わって実行できるツールがあります:paste
$ paste -sd: names.txt
roger:peter:henry
答え2
sed
およびを使用した代替ソリューションtr
:
sed '$!s/$/:/' names.txt | tr -d '\n'
出力:
roger:peter:henry
答え3
paste
は、この作業に適したツールです。ただし、完全を期すために、実行方法を以下に示します。
k="$(head -n1 names.txt)";
for i in $(tail -n+2 names.txt); do
k="$k:$i";
done
これにより、次のものが生成されます。
$ echo "$k"
roger:peter:henry
答え4
$i+=$i":"
これは、あなたが望むことをしません。代わりに、$i
マークされた場所で展開し、その結果をコマンドとして実行しようとします。シェルの割り当てでは、左側のドル記号は使用されません (変数の値を取得すると考えてください。ここでは、変数の値ではなく、格納する場所が必要です)。代わりにそうする必要がありますi+=$i":"
。または、できればi+="$i:"
、シェル変数の展開を引用符で囲む習慣を身に付けてください。
さらに、ループ変数として使用される変数に追加しようとしています。これは、ループの次のラウンドで上書きされるため、あまり役に立ちません。また、最後の項目を含む各項目の後にコロンを追加しているため、最後にコロンが 1 つあります。ただし、後で展開すると削除できます${var%suffix}
。
それで:
s=
for i in $(cat names.txt); do
s+="$i:"
done
s=${s%:}
ただし、引用符で囲まれていない の展開では、$(cat)
ファイル名のワイルドカード パターン (glob) が処理されるため、ファイル内の行*
は現在のディレクトリ内のすべてのファイルに展開されることに注意してください。