ディレクトリ内の複数のCソースファイルをコピーして名前を変更したい。
私はこのようにコピーできます:
$ cp *.c $OTHERDIR
しかし、すべてのファイル名にプレフィックスを付けたいです。
file.c --> old#file.c
これを1ステップで実行するにはどうすればよいですか?
for
ループ:
for f in *.c; do cp -- "$f" "$OTHERDIR/old#$f"; done
私はしばしば-v
オプションをcp
に追加すると、進行状況を監視できます。
シェルグロビングを使用できます。
for f in *.c; do cp -- "$f" "$OTHERDIR/old#$f"; done
for variable in GLOB
形式は glob を一致するすべてのファイル/ディレクトリ(非表示のものを除く)に展開し、それらを反復処理して、それぞれを$variable
(上記の例では)として保存します、$f
)。したがって、私が表示するコマンドは、非表示ではないすべてのファイルを反復処理し、それらをコピーしてプレフィックスを追加します。
さらに別の方法:
for f in $(find dir/ -type f | grep -v 'bk_'); do cp -- "$f" "$(dirname $f)/bk_$(pwgen -s 4 1)_$(basename $f)"; done
このように実行するたびに、dir /が次のようになります。
dir/foo/foo.c
dir/bar/bar.c
dir/baz/baz.c
に:
dir/foo/foo.c
dir/foo/bk_R3pP_foo.c
dir/bar/bar.c
dir/bar/bk_o1JD_bar.c
dir/baz/baz.c
dir/baz/bk_0QqF_baz.c
その後:
dir/foo/foo.c
dir/foo/bk_R3pP_foo.c
dir/foo/bk_dV06_foo.c
dir/bar/bar.c
dir/bar/bk_o1JD_bar.c
dir/bar/bk_B68i_bar.c
dir/baz/baz.c
dir/baz/bk_0QqF_baz.c
dir/baz/bk_p6P3_baz.c
その後...:
dir/foo/foo.c
dir/foo/bk_R3pP_foo.c
dir/foo/bk_dV06_foo.c
dir/foo/bk_2Ar8_foo.c
dir/bar/bar.c
dir/bar/bk_o1JD_bar.c
dir/bar/bk_B68i_bar.c
dir/bar/bk_wX7Z_bar.c
dir/baz/baz.c
dir/baz/bk_0QqF_baz.c
dir/baz/bk_p6P3_baz.c
dir/baz/bk_fPd3_baz.c
.. 等々。
これは、必要に応じて再帰的に行う方法です。
for f in `find . -name \*.c`; do name="${f//\.\//__}"; fileName="${name//\//_}" ; echo "Copying $f as $OTHERDIR/old#$fileName"; cp -- "$f" "$OTHERDIR/$fileName"; done
以下は、xargs
、tr
およびグロビングを使用したワンライナーです。価値があるかもしれません。
echo *.c | tr ' ' '\n' | xargs -n1 -I{} cp "{}" "PREFIX{}"
これにより、*.c
に一致するすべてのファイルがスペース区切りの文字列として返されます。次に、tr
は余分なスペースを改行に変換します(N.B。はスペースを含むファイル名をテストしませんでした**)。次に、xargs
に各ファイル名が入力され、cp
が適切な名前とプレフィックスで実行されます。
*.c
は、他の有用なグロブ用に変更できます。 xargs
およびcp
部分の他の接頭辞も使用できます。
(-print0
をサポートするfind
が必要)上記と同様に、find
を使用して、ファイルのnull-分離リストを出力し、xargs
nullで区切るフラグ付き
find . -name '*.c' -print0 | xargs -0 -n1 -I{} cp "{}" "PREFIX{}"