Linuxの「検索」機能で見つかったファイルをどのようにコピーして名前を変更しますか?


17

/home/user/temps487個のフォルダーがあるという名前のフォルダーがあります。各フォルダーには、thumb.pngというファイルがあります。

thumb.pngという名前のすべてのファイルを別のフォルダーにコピーし、元のフォルダーに基づいて名前を変更します。


それらの名前を変更する方法は?ディレクトリの区切り文字を何かに置き換えた場合-たとえば、下線(_)を使用すると、既に下線が含まれているファイルと衝突する可能性があります。これはすべての有効な文字に当てはまります。また、ファイル名で禁止されている/および\ 0のほかに、セーフハーバーはありません。どの文字でも衝突が発生する可能性があります。
ユーザー不明

フォルダーにはサブフォルダーがありますか、それとも単純で幅の広いフォルダー構造ですか?
ユーザー不明

回答:


8

どうぞ:

for file in /home/user/temps/*/thumb.png; do new_file=${file/temps/new_folder}; cp "$file" "${new_file/\/thumb/}"; done;

編集:

ところで、標準的な知恵findは、これを使用することは悪い考えであるということです-単にシェル拡張を使用する方がはるかに信頼性が高いです。また、これはを前提bashとしていますが、私はそれが安全な前提だと考えています:)

編集2:

明確にするために、それを分類します。

# shell-expansion to loop specified files
for file in /home/user/temps/*/thumb.png; do

    # replace 'temps' with 'new_folder' in the path
    # '/home/temps/abc/thumb.png' becomes '/home/new_folder/abc/thumb.png'
    new_file=${file/temps/new_folder};

    # drop '/thumb' from the path
    # '/home/new_folder/abc/thumb.png' becomes '/home/new_folder/abc.png'
    cp "$file" "${new_file/\/thumb/}";
done;

${var/Pattern/Replacement}コンストラクトの詳細はここで見つけることができます

cp行内の引用符は、ファイル名のスペースや改行などを処理するために重要です。


new_file = new_folder?スラッシュの前のバックスラッシュの目的は何new_file/\/thumbですか?
ユーザー不明

1
@user:${VARIABLE/PATTTERN/REPLACEMENT}の値を生成しますVARIABLEが、パターンは置換テキストに置き換えられます。ここで、パターンは/thumb(の/よう${new_file//PATTERN/REPLACEMENT}に見えないようにエスケープする必要があるため、最初に出現する置換の代わりにグローバル置換になります)、置換テキストは空です。
ジル 'SO-悪であるのをやめる'

もちろん、今ではそれが見えます。:)
ユーザー不明

1
487ディレクトリはの直下/home/user/tempsにあると仮定していますが、これは質問から明らかではありません。そうでない場合は、findまたはが必要**です。
ジル 'SO-悪である停止

@Gilles-確かに、それが質問の読み方です。しかし、ポイントに感謝します:)
サイモン

5

これは、任意の深さのサブディレクトリに対して機能します。

$ find temps/ -name "thumb.png" | while IFS= read -r NAME; do cp -v "$NAME" "separate/${NAME//\//_}"; done
`temps/thumb.png' -> `separate/temps_thumb.png'
`temps/dir3/thumb.png' -> `separate/temps_dir3_thumb.png'
`temps/dir3/dir31/thumb.png' -> `separate/temps_dir3_dir31_thumb.png'
`temps/dir3/dir32/thumb.png' -> `separate/temps_dir3_dir32_thumb.png'
`temps/dir1/thumb.png' -> `separate/temps_dir1_thumb.png'
`temps/dir2/thumb.png' -> `separate/temps_dir2_thumb.png'
`temps/dir2/dir21/thumb.png' -> `separate/temps_dir2_dir21_thumb.png'

関心のある部分はパラメータの拡張 ${NAME//\//_}です。それはの内容を取りNAME、そしてのすべての出現置き換える/とします_

注:結果は、作業ディレクトリと検索用のパスパラメータに依存します。tempsの親ディレクトリからコマンドを実行しました。置換cpechoて実験します。


名前に改行を含むファイルでは失敗します。
ユーザー不明

まあそれは非常にうまくいった。もう1つ、私はいくつかのサブディレクトリにもいくつかのzipファイルを持っています。そこからimgaeを抽出することも可能です。「タールないジップ」覚えて
ミラージュ

1

短いヘルパーコード:

#!/bin/bash
#
# echo cp "$1" ../tmp/"${1//\//_}" 
#
mv "$1" ../tmp/"${1//\//_}"

「deslash.sh」という名前を付けて、実行可能にします。以下で呼び出します:

find -type f -name thumb.png -exec ./deslash.sh {} ";"    

衝突が存在する場合、失敗します

a/b/thumb.png # and 
a_b/thumb.png 

しかし、それは避けられません。


0

これを試して

mkdir /home/user/thumbs
targDir=/home/user/thumbs

cd /home/user/temps

find . -type d | 
 while IFS="" read -r dir ; do
   if [[ -f "${dir}"/thumb.png ]] ; then
     echo mv -i "${dir}/thumb.png" "${targDir}/${dir}_thumb.png"
   fi
done

編集

ディレクトリ名に空白文字が埋め込まれている場合の引用を追加しました。

また、実行するコマンドのみを出力するように変更しました。スクリプトの出力を調べて、すべてのファイル/パス名が適切に見えることを確認します。実行されるコマンドに問題がないことを確認したら、を削除しechoます。


私はいくつかのPNGファイルをいくつかのサブフォルダに持っています、それは動作しますか
Mirage

私の「A A」フォルダの場合、以下を生成mv -i ./A A/thumb.png ../tmp/.pngします。
ユーザー不明

上記のコードのすべての変数を引用符と中括弧で囲んでください。例: "$ {dir}"
shellter

@ Mirror51は次のように書いています。はい、そうすべきです。このスクリプトの各ステップを個別に実行できることをご存知でしたか(または、一緒にパイプされると、各パイプのセット)。あなただけを実行してfind -type d、出力を見ることができます。それはあなたが期待するすべてのディレクトリを取得しますか?そうでない場合は、問題を示すために出力を追加してください。幸運を。
シェルター

動作しません。read dirワード分割を実行し、ディレクトリa\nbaとbから2つのインスタンスを取得しますが、マスキングでは解決できません。
ユーザー不明

-1

コピーするには、コマンドcpが必要です。また、linuxの名前を変更することは、ファイルを移動することと同じなので、mvコマンドで実行する必要があります。Linuxでは、もちろん、ソースから別のフォルダーにある場合はもちろん、宛先フォルダーへのパス全体を指定する必要があります。私はコピーのために、このようなものになるだろう:

cp /source_path/file /destination_path/

または名前を変更または移動する

mv /source_path/old_file /destination_path/new_name_file

これは、ポスターの質問のほんの一部です。次に、ディレクトリを反復処理してサムネイルをコピーする方法を説明します:

OPが使用したいfind

はい、あなたは右...私は...私に何が起こったのかわからないしている
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.