ファイルセットの1つのファイルのみをエコーし​​ます。

ファイルセットの1つのファイルのみをエコーし​​ます。

cp配列を使用して、あるディレクトリから別のディレクトリに2つ以上のファイルをコピーしようとしています。
私は以下を実行しました:

files=(
    LocalSettings.php
    robots.txt
    .htaccess
    ${domain}.png
    googlec69e044fede13fdc.htm
)

ファイル名はテーブルを使用してインデントされます。

私の目標は、次の後に実行することです。

cp -a "source_path/${files[@]}" "/destanation_path"

私の問題は、変数自体をテストすると、ファイルの完全なリストではなく最初の
echo $filesファイル名のみが返されることです。これをどのように説明しますか? 関連:LocalSettings.php

マルチラインモードcp;

答え1

そのBash機能は次のように説明されていますman bash

添え字なしで配列変数を参照することは、添字0を持つ配列を参照するのと同じです。

filesアレイのすべてのメンバーを印刷するには、次の手順を実行します。

echo "${files[@]}"

次のトピックでも説明されていますman bash

${name[@]} は、名前の各要素を別々の単語に展開します。

答え2

$filesリスト(質問の項目など)の場合も${files[0]}同じです。files

リストの最初の要素の前にのみ"source_path/${files[@]}"配置されることに注意してください。source_path/各要素の前にいくつかのパスが付けられるようにリストを変更するには、次のようにします。

files=( ... your list of files ... )

for element in "${files[@]}"; do
    files=( "${files[@]:1}" "source_path/$element" )
done

cp "${files[@]}" destanation_path

または、実行cd前に実際の名前にパスを追加したり、リストから最初に値を割り当てながら追加することもできます。source_pathcp

答え3

他の人が指摘したように、配列$filesの最初の要素にのみ拡張され、最初の要素"source_path/${files[@]}"にのみ "source_path/"が追加されます。しかし、すべての要素をインポートして各要素の前にパスを追加する比較的簡単な方法があります。

cp -a "${files[@]/#/source_path/}" "/destanation_path"

これは、[@]要素全体の拡張()と置換を組み合わせます。/#「文字列の先頭から置換」、置き換える空の文字列、区切り文字、/置換項目(/add)として「source_path/」を意味します。これにより、各要素にソースパスが追加され、一部のバージョンのように要素の面白い文字が混乱しなくなります。

上記の例では、「source_path/」は末尾にスラッシュがありますが、先頭にはスラッシュはありません。前の「/」は区切り記号です。スラッシュで始まり、「/source/path/」など、より多くのスラッシュが含まれていても動作します。

cp -a "${files[@]/#//source/path/}" "/destanation_path"

答え4

次のコードスニペットを試すこともできます。

IFS=$'\n'
cp -a $( printf "source_path/%s\n" "${files[@]}" ) /destination_path/

スペースを含むファイル名にも機能します。

関連情報