Anda sangat dekat.
seq 15 -1 1 | xargs [email protected] sh -c 'mv @_* @'
Anda perlu menunda interpretasi (ekspansi) dari *
sampai setelah @
substitusi telah terjadi. (Tapi Anda sudah mengerti bahwa itulah masalahnya, bukan?)
Saya telah disarankan untuk tidak menyematkan nama file yang tidak dikenal (atau string substitusi lainnya) langsung ke baris perintah shell. Contoh di atas mungkin cukup aman, karena Anda tahu apa yang akan menjadi string —15
, 14
, …, 3
, 2
dan 1
. Tapi menggunakan contoh di atas sebagai template untuk perintah yang lebih kompleks bisa berbahaya. Pengaturan yang lebih aman adalah
seq 15 -1 1 | xargs [email protected] sh -c 'mv -- "$1"_* "$1"' x-sh @
di mana x-sh
adalah string semi-arbitrer yang akan digunakan untuk melabeli setiap pesan kesalahan yang dikeluarkan oleh shell yang dipanggil. Ini setara dengan contoh pertama saya, kecuali, daripada menyematkan string (diwakili oleh @
) langsung ke perintah shell, ia menyuntikkannya dengan memberikan @
sebagai argumen ke shell, lalu mereferensikannya sebagai "$1"
.
P.S. Anda menyarankan menjalankan seq
perintah secara terbalik (seq 15 -1 1
, yang menghasilkan 15
, 14
, …, 3
, 2
, 1
bukan 1
, 2
, 3
, …, 14
, 15
) dan tidak ada yang menyebutkannya. Ini akan menjadi bagian penting dari jawaban jika nama file Anda seperti 1foo.txt
, 2bar.asc
, dan 13test.png
, dll. (dengan berbagai karakter muncul setelah angka, bukan selalu _
). Dalam hal ini, perintahnya adalah mv "$1"* "$1"
(tanpa _
), dan, jika Anda melakukan 1
terlebih dahulu, lalu perintah mv 1* 1
akan menyapu semua 10quick*
, 11brown*
, 12fox*
, dll., file, bersama dengan 1foo*
file. Tapi
seq 1 15 | xargs [email protected] sh -c 'mv -- "$1"_* "$1"' x-sh @
harus aman.
P.P.S. seq
perintah tidak ditentukan oleh POSIX. Juga tidak ada ekspansi brace di shell. Solusi yang sesuai dengan POSIX dapat dibangun dengan menggabungkan jawaban gravitasi untuk pertanyaan ini dengan jawaban lain dari Adam Katz:
i=1
while [ "$i" -le 15 ]
do
mv -- "${i}"_* "$i"
i=$((i+1))
done
P.P.P.S. Tidaklah penting ketika Anda mengetahui bahwa nama file dimulai dengan karakter alfanumerik (yaitu, huruf dan angka), tetapi, dalam kasus yang lebih umum, Anda harus menggunakan --
antara nama perintah dan argumen. Ini meningkatkan penanganan nama file yang dimulai dengan tanda hubung. --
memberi tahu perintah untuk memperlakukan argumen (nama file)sebagai argumen. Tanpanya, argumen seperti itu dapat diperlakukan sebagai string opsi.
Jangan gunakan xargs
untuk itu. Gunakan for
lingkaran:
for i in $(seq 1 15); do
mv ${i}_* $i
done
Bahkan lebih baik menggunakan ekspansi brace daripada seq
:
mkdir {1..15}
for i in {1..15}; do
mv ${i}_* $i
done