Gunakan -I
opsi:
echo prefix | xargs -I % echo % post
Keluaran:
prefix post
Ini adalah salah satu cara untuk melakukannya
pdftk $(ls | sort -n) cat output combinewd2.pdf
atau menggunakan backtick
pdftk `ls | sort -n` cat output combinewd2.pdf
Misalnya, jika nama file adalah 100, 2, 9, 3.14, 10, 1 perintahnya adalah
pdftk 1 2 3.14 9 10 100 cat output combinewd2.pdf
Untuk menangani nama file dengan spasi atau karakter khusus lainnya, pertimbangkan ini diperbaiki versi luar biasa @joeytwiddle jawaban (yang tidak mengurutkan secara numerik, lihat pembahasan di bawah):
#-- The following will handle special characters, and
# will sort filenames numerically
# e.g. filenames 100, 2, 9, 3.14, 10, 1 results in
# ./1 ./2 ./3.14 ./9 ./10 ./100
#
find . -maxdepth 1 -type f -print0 |
sort -k1.3n -z -t '\0' |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Alternatif untuk xargs (khusus bash)
xargs
adalah perintah eksternal, pada contoh sebelumnya memanggil sh
yang pada gilirannya memanggil pdftk
.
Alternatifnya adalah menggunakan mapfile
bawaan jika tersedia, atau gunakan parameter posisi. Contoh berikut menggunakan dua fungsi, print0_files menghasilkan nama file yang diakhiri NUL dan create_pdf memanggil pdftk
:
print0_files | create_pdf combinewd2.pdf
Fungsi didefinisikan sebagai berikut
#-- Generate the NUL terminated filenames, numerically sorted
print0_files() {
find . -maxdepth 1 -type f -print0 |
sort -k1.3n -z -t '\0'
}
#-- Read NUL terminated filenames using mapfile
create_pdf() {
mapfile -d ''
pdftk "${MAPFILE[@]}" cat output "$1"
}
#-- Alternative using positional parameters
create_pdf() {
local -r pdf=$1
set --
while IFS= read -r -d '' f; do set -- "[email protected]" "$f"; done
pdftk "[email protected]" cat output "$pdf"
}
Diskusi
Seperti yang ditunjukkan dalam komentar, jawaban awal yang sederhana tidak berfungsi dengan nama file yang mengandung spasi atau karakter khusus lainnya. Jawaban oleh @joeytwiddle menangani karakter khusus, meskipun tidak diurutkan secara numerik
#-- The following will not sort numerically due to ./ prefix,
# e.g. filenames 100, 2, 9, 3.14, 10, 1 results in
# ./1 ./10 ./100 ./2 ./3.14 ./9
#
find . -maxdepth 1 -type f -print0 |
sort -zn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Itu tidak mengurutkan secara numerik karena setiap nama file diawali dengan ./
oleh find
memerintah. Beberapa versi find
dukungan perintah -printf '%P\0'
yang tidak menyertakan ./
awalan. Perbaikan portabel yang lebih sederhana adalah dengan menambahkan -d, --dictionary-order
ke sort
perintah sehingga hanya mempertimbangkan spasi kosong dan karakter alfanumerik sebagai perbandingan, tetapi mungkin masih menghasilkan urutan yang salah
#-- The following will not sort numerically due to decimals
# e.g. filenames 100, 2, 9, 3.14, 10, 1 results in
# ./1 ./2 ./9 ./10 ./100 ./3.14
#
find . -maxdepth 1 -type f -print0 |
sort -dzn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Jika nama file berisi desimal, ini dapat menyebabkan pengurutan numerik yang salah. sort
perintah tidak memungkinkan offset ke bidang saat menyortir, sort -k1.3n
, seseorang harus berhati-hati dalam menentukan pemisah bidang jika nama file dibuat seumum mungkin, untungnya sort -t '\0'
menentukan NUL sebagai pemisah bidang, dan find -print0
opsi menunjukkan NUL digunakan sebagai pembatas antara nama file, jadi sort -z -t '\0'
menentukan NUL sebagai pembatas catatan dan pemisah bidang-- setiap nama file kemudian menjadi catatan bidang tunggal. Mengingat hal itu, kita kemudian dapat mengimbangi ke dalam bidang tunggal dan melewati ./
awalan dengan menentukan karakter ke-3 dari bidang ke-1 sebagai posisi awal untuk pengurutan numerik, sort -k1.3n -z -t '\0'
.
Ini harus bekerja pada nama file yang berisi spasi, baris baru, apostrof, dan tanda kutip (semuanya dimungkinkan pada sistem file UNIX):
find . -maxdepth 1 -type f -print0 |
sort -zn |
xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"
Itu mungkin berlebihan dibandingkan dengan jawaban yang diterima, jika Anda tahu Anda bekerja dengan nama file sederhana.
Namun jika Anda menulis skrip yang akan digunakan lagi di masa mendatang, diharapkan skrip tersebut tidak akan meledak suatu hari saat bertemu dengan masukan yang tidak biasa (namun valid).
Ini pada dasarnya adalah adaptasi dari jawaban andrewdotn yang menghentikan file input dengan byte nol, bukan dengan baris baru, sehingga mempertahankan nama file yang berisi satu atau lebih karakter baris baru.
Opsi masing-masing -print0
, -z
dan -0
beri tahu setiap program bahwa input/output harus dibatasi oleh byte nol. Tiga program berbeda, tiga argumen berbeda!
Jelek, tapi Anda bisa menjalankan sh -c
dan akses daftar argumen yang diteruskan oleh xargs
sebagai "${@}"
, seperti ini:
ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "${0}"
"${0}"
ekstra pada akhirnya ada karena, sebagai sh
kata halaman manual
-c tali
Jika -c ada opsi, maka perintah dibaca dari string . Jika ada argumen setelah string , mereka ditetapkan ke parameter posisi, dimulai dengan $0 .
Untuk mengujinya, pertama mari kita buat beberapa file dengan nama rumit yang akan mengacaukan sebagian besar solusi lain:
$ seq 1 100 | xargs -I{} touch '{} with "spaces"'
$ ls
1 with "spaces" 31 with "spaces" 54 with "spaces" 77 with "spaces"
10 with "spaces" 32 with "spaces" 55 with "spaces" 78 with "spaces"
100 with "spaces" 33 with "spaces" 56 with "spaces" 79 with "spaces"
11 with "spaces" 34 with "spaces" 57 with "spaces" 8 with "spaces"
12 with "spaces" 35 with "spaces" 58 with "spaces" 80 with "spaces"
13 with "spaces" 36 with "spaces" 59 with "spaces" 81 with "spaces"
14 with "spaces" 37 with "spaces" 6 with "spaces" 82 with "spaces"
15 with "spaces" 38 with "spaces" 60 with "spaces" 83 with "spaces"
16 with "spaces" 39 with "spaces" 61 with "spaces" 84 with "spaces"
17 with "spaces" 4 with "spaces" 62 with "spaces" 85 with "spaces"
18 with "spaces" 40 with "spaces" 63 with "spaces" 86 with "spaces"
19 with "spaces" 41 with "spaces" 64 with "spaces" 87 with "spaces"
2 with "spaces" 42 with "spaces" 65 with "spaces" 88 with "spaces"
20 with "spaces" 43 with "spaces" 66 with "spaces" 89 with "spaces"
21 with "spaces" 44 with "spaces" 67 with "spaces" 9 with "spaces"
22 with "spaces" 45 with "spaces" 68 with "spaces" 90 with "spaces"
23 with "spaces" 46 with "spaces" 69 with "spaces" 91 with "spaces"
24 with "spaces" 47 with "spaces" 7 with "spaces" 92 with "spaces"
25 with "spaces" 48 with "spaces" 70 with "spaces" 93 with "spaces"
26 with "spaces" 49 with "spaces" 71 with "spaces" 94 with "spaces"
27 with "spaces" 5 with "spaces" 72 with "spaces" 95 with "spaces"
28 with "spaces" 50 with "spaces" 73 with "spaces" 96 with "spaces"
29 with "spaces" 51 with "spaces" 74 with "spaces" 97 with "spaces"
3 with "spaces" 52 with "spaces" 75 with "spaces" 98 with "spaces"
30 with "spaces" 53 with "spaces" 76 with "spaces" 99 with "spaces"
$ ls | sort -n | xargs -d'\n' sh -c 'set -x; pdftk "${@}" cat output combinewd2.pdf' "${0}"
+ pdftk '1 with "spaces"' '2 with "spaces"' '3 with "spaces"' '4 with "spaces"' '5 with "spaces"' '6 with "spaces"' '7 with "spaces"' '8 with "spaces"' '9 with "spaces"' '10 with "spaces"' '11 with "spaces"' '12 with "spaces"' '13 with "spaces"' '14 with "spaces"' '15 with "spaces"' '16 with "spaces"' '17 with "spaces"' '18 with "spaces"' '19 with "spaces"' '20 with "spaces"' '21 with "spaces"' '22 with "spaces"' '23 with "spaces"' '24 with "spaces"' '25 with "spaces"' '26 with "spaces"' '27 with "spaces"' '28 with "spaces"' '29 with "spaces"' '30 with "spaces"' '31 with "spaces"' '32 with "spaces"' '33 with "spaces"' '34 with "spaces"' '35 with "spaces"' '36 with "spaces"' '37 with "spaces"' '38 with "spaces"' '39 with "spaces"' '40 with "spaces"' '41 with "spaces"' '42 with "spaces"' '43 with "spaces"' '44 with "spaces"' '45 with "spaces"' '46 with "spaces"' '47 with "spaces"' '48 with "spaces"' '49 with "spaces"' '50 with "spaces"' '51 with "spaces"' '52 with "spaces"' '53 with "spaces"' '54 with "spaces"' '55 with "spaces"' '56 with "spaces"' '57 with "spaces"' '58 with "spaces"' '59 with "spaces"' '60 with "spaces"' '61 with "spaces"' '62 with "spaces"' '63 with "spaces"' '64 with "spaces"' '65 with "spaces"' '66 with "spaces"' '67 with "spaces"' '68 with "spaces"' '69 with "spaces"' '70 with "spaces"' '71 with "spaces"' '72 with "spaces"' '73 with "spaces"' '74 with "spaces"' '75 with "spaces"' '76 with "spaces"' '77 with "spaces"' '78 with "spaces"' '79 with "spaces"' '80 with "spaces"' '81 with "spaces"' '82 with "spaces"' '83 with "spaces"' '84 with "spaces"' '85 with "spaces"' '86 with "spaces"' '87 with "spaces"' '88 with "spaces"' '89 with "spaces"' '90 with "spaces"' '91 with "spaces"' '92 with "spaces"' '93 with "spaces"' '94 with "spaces"' '95 with "spaces"' '96 with "spaces"' '97 with "spaces"' '98 with "spaces"' '99 with "spaces"' '100 with "spaces"' cat output combinewd2.pdf
Semua argumen dikutip dengan benar. Perhatikan bahwa ini akan gagal jika ada nama file yang berisi baris baru, dan ls -v
itu pada dasarnya adalah ls | sort -n
.