ファイル名に基づいて他のファイルにファイルをコピーできるコマンドはLinuxにありますか? [閉鎖]

ファイル名に基づいて他のファイルにファイルをコピーできるコマンドはLinuxにありますか? [閉鎖]

a_b_c_d.jpg、、、、などのファイルにコピーして各ファイルが元のコピーになるようにするLinuxコマンドはありますか?a.jpgb.jpgc.jpgd.jpg

元の名前から名前を抽出し、最初に区切り、最初に_終わる必要があります.

答え1

#!/bin/sh

for name in *_*.jpg; do
    # Only care about regular files
    [ ! -f "$name" ] && continue

    # Do the following in a subshell to avoid affecting the original 
    # environment with "set -f" and setting IFS
    (
        set -f    # Turn off filename globbing (allows filename to contain e.g. *)
        IFS='_'   # Split unquoted strings on "_" only

        # Split the filename into parts (remove trailing ".jpg" first), and then
        # iterate over the parts, creating the symbolic links
        for part in ${name%.jpg}; do
            ln -s -- "$name" "$part.jpg"

            # To do copying instead, use:
            # cp -i -- "$name" "$part.jpg"
        done
    )
done

.jpgスクリプトには、1つ以上の下線が含まれ、現在のディレクトリで終わるすべてのファイル名を繰り返します。これらの名前ごとに、名前をアンダースコアに分割して作成します。シンボリックリンク名前部分を分割(.jpgファイル名のサフィックスを追加)して、元のファイル(コピーではありません)にします。

私は元のファイルの実際のコピーではなくシンボリックリンクを作成することにしました。本当にコピーしたい場合は、スクリプトコメントでそのコードを見つけることができます。

両方のファイルが含まれているディレクトリで実行すると、次のようにa_b_c_d.jpgなります。ABBA_hello there_misc.jpg

.
|-- ABBA.jpg -> ABBA_hello there_misc.jpg
|-- ABBA_hello there_misc.jpg
|-- a.jpg -> a_b_c_d.jpg
|-- a_b_c_d.jpg
|-- b.jpg -> a_b_c_d.jpg
|-- c.jpg -> a_b_c_d.jpg
|-- d.jpg -> a_b_c_d.jpg
|-- hello there.jpg -> ABBA_hello there_misc.jpg
`-- misc.jpg -> ABBA_hello there_misc.jpg

答え2

次のように見えます。

for FN in *.jpg; do IFS="_."; AR=($FN); for i in "${AR[@]}"; do [ ! "$i" = "jpg" ] &&  echo cp "$FN" "$i".jpg; done; done
cp a_b_c_d.jpg a.jpg
cp a_b_c_d.jpg b.jpg
cp a_b_c_d.jpg c.jpg
cp a_b_c_d.jpg d.jpg

より多くのエラーチェック、IFSプロテクタを追加し、echo満足のいくものを削除するなどのタスクを実行できます。

編集するKusalanandaのコメントに基づいて編集されました。

for FN in *.jpg; do IFS="_"; for i in ${FN%.jpg}; do echo cp "$FN" "$i".jpg; done; done

答え3

簡単な方法は...

for x in a b c d
do
  cp a_b_c_d.jpg $x.jpg
done

a b c dその部分を指定せずに、ファイル名から取得するよりプログラム的な方法でこれを実行したいと思います。

この場合、ファイル名を取得して2回分割する必要があります。.まず、発生に基づいてファイル拡張子をインポートしてから、再発生に基づいてファイル_名を取得する必要があります。これは次の方法で行うことができます。IFSそして、上記の元の例で行ったように、ファイル名配列のループを実行します。

答え4

まあ、簡単なスクリプトを書いた

#!/bin/bash
for filename in *_*.jpg; do
   n=$(echo "$filename" | awk -F '_' '{print NF}')
   for ((i=1; i<$n;i++)) ;do
      cp "$filename" "$(echo "$filename" | awk -F '_' '{print '"\$$i"'}')".jpg
   done
   cp "$filename" "$(echo "$filename" | awk -F '_' '{print '"\$$n"'}')"
done

jpg1つ以上の.dllを含むファイルを検索し、_それcp "$filename" "$(echo "$filename" | awk -F '_' '{print '"\$$i"'}')".jpgを使用して元のファイルをコピーします。ただし、最後のパラメータには.jpg拡張子が含まれているため、.expansionなしでforループの外部に別々に作成しました.jpg

関連情報