Làm thế nào để sao chép và thêm tiền tố vào tên tệp trong một bước?


7

Tôi muốn sao chép và đổi tên nhiều tập tin nguồn c trong một thư mục.

Tôi có thể sao chép như thế này:

$ cp *.c $OTHERDIR

Nhưng tôi muốn cung cấp một tiền tố cho tất cả các tên tệp:

file.c --> old#file.c

Làm thế nào tôi có thể làm điều này trong 1 bước?

Câu trả lời:


18

một forvòng lặp:

for f in *.c; do cp -- "$f" "$OTHERDIR/old#$f"; done

Tôi thường thêm -vtùy chọn cpđể cho phép tôi xem tiến trình.


7

Bạn có thể sử dụng shell globalbing:

for f in *.c; do cp -- "$f" "$OTHERDIR/old#$f"; done

Các for variable in GLOBđịnh dạng sẽ mở rộng glob để tất cả các file phù hợp / thư mục (trừ ẩn-one) và lặp qua chúng, tiết kiệm mỗi lần lượt là $variable(trong ví dụ trên, $f). Vì vậy, lệnh tôi hiển thị sẽ lặp lại trên tất cả các tệp không bị ẩn, sao chép chúng và thêm tiền tố.


Nếu tôi làm for f in /foo/bar/*.c, $fsẽ chứa toàn bộ đường dẫn, thay vào đó chỉ là tên của tệp. Làm thế nào tôi có thể chỉ có được tên của tập tin?
alexandernst

1
@alexandernst hoặc cd /foo/bar/; for f in *c, hoặc sử dụng for f in /foo/bar/*.c; do name=${f##*/} ...hoặc name=$(basename "$f").
terdon

1

Vẫn còn một cách khác:

for f in $(find dir/ -type f | grep -v 'bk_'); do cp -- "$f" "$(dirname $f)/bk_$(pwgen -s 4 1)_$(basename $f)"; done

Mỗi khi bạn chạy theo cách này, nó sẽ chuyển dir / from:

dir/foo/foo.c
dir/bar/bar.c
dir/baz/baz.c

Vào:

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

Và sau đó:

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

Và sau đó...:

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

.. và như thế.


Đừng lặp qua findđầu ra . Đừng sử dụng grepđể loại trừ tên tệp khi findmột mình có thể làm điều đó.
don_crissti


0

Đây là một lót sử dụng xargs, trvà Globing. Có thể có một số giá trị.

echo *.c | tr ' ' '\n' | xargs -n1 -I{} cp "{}" "PREFIX{}"

Điều này trả về tất cả các tệp khớp với nhau *.cnhư một chuỗi được phân tách bằng dấu cách. Tiếp theo, trbiến các khoảng trắng thừa thành dòng mới ( NB không kiểm tra tên tệp có khoảng trắng **). Sau đó, xargsđược điền với mỗi tên tệp và chạy cpvới tên và tiền tố thích hợp.

*.ccó thể được sửa đổi cho các quả cầu khác, hữu ích. Các tiền tố khác trong xargscpmột phần cũng có thể được sử dụng.

** cho những người có không gian trong tên tệp của họ:

(yêu cầu findhỗ trợ mà -print0) Tương tự như trên, chúng ta có thể sử dụng findđể sản xuất một danh -seperated của tác phẩm, và tinh chỉnh xargsvới một lá cờ để tách trên rỗng

find . -name '*.c' -print0 | xargs -0 -n1 -I{} cp "{}" "PREFIX{}"

1
Và, nếu bạn đã thử nghiệm điều này với tên tệp chứa khoảng trắng, bạn sẽ thấy nó thất bại.
Scott

1
Cảm ơn đã gọi ra. Tôi biết nó có thể thất bại nhưng nghĩ rằng tôi đã chần chừ trong suốt ngày làm việc của mình với lần đầu tiên vượt qua. 😀
TonyH
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.