whileループ中、「cp:ターゲット '...'はディレクトリではありません。」

whileループ中、「cp:ターゲット '...'はディレクトリではありません。」

名前を短くしたいファイルディレクトリがあります。

(3) andrew@andrew Learning_Plans $ ls -al
total 580
drwxr-xr-x 2 andrew andrew  4096 Apr 10 21:40 .
drwxr-xr-x 7 andrew andrew  4096 Apr 10 16:46 ..
-rw-rw-rw- 1 andrew andrew 17825 Mar 25 14:18 Edexcel International GCSE Physics Chapter 10 Properties of Waves Learning Plan.docx
-rw-rw-rw- 1 andrew andrew 18472 Mar 25 14:19 Edexcel International GCSE Physics Chapter 11 The Electromagnetic Spectrum Learning Plan.docx
-rw-rw-rw- 1 andrew andrew 18692 Mar 25 14:19 Edexcel International GCSE Physics Chapter 12 Light Waves Learning Plan.docx
:
etc

コマンドラインから次のコマンドを実行しました。

while read x; do echo cp \'$x\' $(echo $x | cut -b38- | tr ' ' '_'); done < <(find . -type f)

これは私が期待するものを生成します。

cp './Edexcel International GCSE Physics Chapter 17 Energy Resources and Electricity Generation Learning Plan.docx' Chapter_17_Energy_Resources_and_Electricity_Generation_Learning_Plan.docx
cp './Edexcel International GCSE Physics Chapter 19 Solids, Liquids and Gases Learning Plan.docx' Chapter_19_Solids,_Liquids_and_Gases_Learning_Plan.docx
cp './Edexcel International GCSE Physics Chapter 28 Cosmology Learning Plan.docx' Chapter_28_Cosmology_Learning_Plan.docx
:
etc

しかし、、エコーを削除すると、次のようになります。

cp: target ‘Chapter_17_Energy_Resources_and_Electricity_Generation_Learning_Plan.docx’ is not a directory
cp: target ‘Chapter_19_Solids,_Liquids_and_Gases_Learning_Plan.docx’ is not a directory
cp: target ‘Chapter_28_Cosmology_Learning_Plan.docx’ is not a directory
:
etc

ファイル名のスペースに関連しているようですが、一重引用符で問題を解決できますか?

echoの出力を端末にコピー/貼り付けしようとしましたが、うまくいきました! whileループでは実行されません。

バージョン:

(3) andrew@andrew Learning_Plans $ bash --version
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
(3) andrew@andrew Learning_Plans $ cat /etc/*release
DISTRIB_ID=LinuxMint
DISTRIB_RELEASE=17.3
DISTRIB_CODENAME=rosa
DISTRIB_DESCRIPTION="Linux Mint 17.3 Rosa"
NAME="Ubuntu"
VERSION="14.04, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

ベストアンサー1

問題はファイル名の空白です。ファイル名はスペースで区切られます。cp3つ以上のパラメータを取得する場合は、最後のパラメータはディレクトリである必要があります。そうではなくて文句を言います。

Edexcel International GCSE Physics安全な方法で各ファイル名から文字列を削除し、スペースをアンダースコアに変換するには(in bash)を使用します。

for name in 'Edexcel International GCSE Physics '*.docx; do
    newname=${name#Edexcel International GCSE Physics }
    newname=${newname// /_}

    mv -i "$name" "$newname"
done

次に、現在のディレクトリ内のすべての関連ファイルを繰り返し、newname最初に名前の先頭から既知の部分文字列を削除し、残りのスペースを下線に変換して変数に新しい名前を作成します。次に、古い名前を新しい名前に置き換えます。

コードのようにファイルのコピーを作成したい場合は、に変更してくださいmvcp

テスト:

$ ls
Edexcel International GCSE Physics Chapter 10 Properties of Waves Learning Plan.docx
Edexcel International GCSE Physics Chapter 11 The Electromagnetic Spectrum Learning Plan.docx
Edexcel International GCSE Physics Chapter 12 Light Waves Learning Plan.docx

(ここでループが実行されます)

$ ls
Chapter_10_Properties_of_Waves_Learning_Plan.docx
Chapter_11_The_Electromagnetic_Spectrum_Learning_Plan.docx
Chapter_12_Light_Waves_Learning_Plan.docx

この関数を複数のサブディレクトリに繰り返し適用しますか?

find . -type f -name 'Edexcel International GCSE Physics *.docx' -exec sh -c '
    for pathname; do
        name=$(basename "$pathname")

        newname=${name#Edexcel International GCSE Physics }
        newname=${newname// /_}

        mv -i "$pathname" "$(dirname "$pathname")/$newname"
    done' sh {} +

関連:

おすすめ記事