ネストされたワイルドカードを使用したコピーと名前の変更

ネストされたワイルドカードを使用したコピーと名前の変更

次のファイル構造があります。

raw:
    F1:
        file1.pdf
    F2:
        file2.pdf
    (...)
pdf:
    (...)

フォルダごとに常に1つのPDFファイルのみがあり、ファイル/フォルダ名は任意に指定できます。

rawディレクトリ内のすべてのpdfファイルをpdfディレクトリにコピーし、そのファイル名をルートフォルダ名に変更したいと思います。上記の例では、結果は次のようになります。

raw:
    F1:
        file1.pdf
    F2:
        file2.pdf
    (...)
pdf:
    F1.pdf
    F2.pdf
    (...)

ワイルドカードのコピーについて読みましたが、ファイルをコピーするには2つのネストされたワイルドカードを使用する必要があるため、これは問題があるようです。したがって、これは明らかに機能しません。

cp raw/*/*.pdf pdf/*.pdf

この問題を解決する方法はありますか?それとも私のフォルダを繰り返し、正規表現を使ってパスを分割する必要がありますか?

ベストアンサー1

コピーにワイルドカードを使用できます。ただし、ファイルをコピーするのではなく、ファイル名を変更する必要があります。つまり、各ファイルに新しい名前を割り当てる必要があるため、ループは避けられません。せいぜいループを実行するツールを使用できます。

perl-renamerenamedDebianベースのシステムから呼び出す)場合は、次のことができます。

$ rename -n 's|raw/([^/]+)/.*pdf|pdf/$1.pdf|' raw/*/*.pdf
raw/F1/file1.pdf -> pdf/F1.pdf
raw/F2/file2.pdf -> pdf/F2.pdf

.pdfこれにより、これを行うのではなく、終わるすべてのファイル名を見つけることがrawできます.pdf。したがって、満足している場合は、実際にファイル名を変更せずにそのコマンドを実行してください。pdf/-n-n

rename 's|raw/([^/]+)/.*pdf|pdf/$1.pdf|' raw/*/*.pdf

または、シェルループを使用できます。

for f in raw/*/*pdf; do 
    new=$(sed -E 's|raw/([^/]+)/.*|pdf/\1.pdf|' <<<"$f"); 
    echo "mv -- $f $new"; 
done
mv raw/F1/file1.pdf pdf/F1.pdf
mv raw/F2/file2.pdf pdf/F2.pdf

もう一度、うまくいけば、エコーを削除して実際にファイル名を変更します。

for f in raw/*/*pdf; do 
    new=$(sed -E 's|raw/([^/]+)/.*|pdf/\1.pdf|' <<<"$f"); 
    mv -- "$f" "$new"; 
done

重要:両方のソリューションがディレクトリごとに1つのファイルしかないと仮定しているため、競合は発生しません。同じサブディレクトリにあるすべてのファイルは同じ名前を持つため、追加のファイルが削除されます。

-i各ツールのオプション(mvan)を使用すると、rename同じ名前のファイルを上書きする前に確認メッセージが表示されます。これにより解決策が作成されます。

rename -i 's|raw/([^/]+)/.*pdf|pdf/$1.pdf|' raw/*/*.pdf

そして

for f in raw/*/*pdf; do 
    new=$(sed -E 's|raw/([^/]+)/.*|pdf/\1.pdf|' <<<"$f"); 
    mv -i -- "$f" "$new"; 
done

おすすめ記事