「echo」で取得した出力は、端末に貼り付けるとコマンドとして機能しますが、スクリプト内では機能しません。

「echo」で取得した出力は、端末に貼り付けるとコマンドとして機能しますが、スクリプト内では機能しません。

残念ながら、多くの場合、スペースを含むアプリケーションによって生成されたファイルを変更しようとします。端末にコピーして貼り付けると、動作する出力を提供するために「エコー」が得られましたが、コマンドを実行しようとすると機能しません。私が探していますこれ答え、以前は役に立ちましたが、この場合は "${x}"構文も機能しないようです。

#!/bin/sh
cd ~/Data
IFS=$'\n';for i in $(ls); do
    echo "$i";
    filename="$i"
    date=$(date -n +%Y-%m-%d)
    new_filename="$date$filename"
    echo mv \'"${filename}"\' \'"${new_filename}"\'
    mv \'"${filename}"\' \'"${new_filename}"\'
done;

答え1

主な問題は、出力lsコマンドを繰り返すことです。グローブを使う*

#!/bin/sh
cd ~/Data
for i in *; do
    echo "$i"
    filename="$i"
    date=$(date -n +%Y-%m-%d)
    new_filename="${date}${filename}"
    echo mv "${filename}" "${new_filename}"
    mv -- "${filename}" "${new_filename}"
done

また、名前を正しく処理する--ために追加しました。しかし、私のコマンドにはオプションはありませんが、別のバージョンがある可能性があるため、そのままにしておきます。mv-date-n

答え2

別の問題は、mv行に追加の引用符があることです。 echoを使用してシェルにコピーするコマンドを印刷するときは、すべてを2回引用する必要があります。一度はこのシェルについて、一度は2番目のシェルについて引用する必要があります。ファイル名がダッシュで始まらない場合、または一重引用符が含まれていない限り、echo mvは正しく機能します。 mvは一度だけ参照してください。

コードスニペットを書き換える方法は次のとおりです。

#!/bin/bash
cd ~/Data
date="$(date -n +%Y-%m-%d)"

for filename in *; do
    echo "${filename}"
    new_filename="$date$filename"
    filename_e="$(echo "$filename"|sed -e 's!\('\''\)!\\\1!')"
    new_filename_e="$(echo "$new_filename"|sed -e 's!\('\''\)!\\\1!')"
    echo mv -- \'"${filename_e}"\' \'"${new_filename_e}"\'
    mv -- "${filename}" "${new_filename}"
done;

このバージョンは、名前に文字を含むすべてのファイルの名前を正しく変更します。唯一の制限は、echoedコマンドが名前に改行文字を含むファイルで機能しないコマンドを生成できることです。

答え3

\スペースの前にエスケープ文字を追加してファイル名を処理します。

filename=$(echo $i|sed 's/ /\\ /g')
mv $filename $new_filename

関連情報