Linux ですべてのファイルを 1 つの引数として渡したいのですが、それができません。
これは機能しています
ls | sort -n | xargs -i pdftk {} cat output combinewd2.pdf
これはコマンドごとに 1 つの引数を渡しますが、すべてを 1 つのコマンドにまとめたいと思います。
これはそれを行う1つの方法です
pdftk $(ls | sort -n) cat output combinewd2.pdf
またはバックティックを使用する
pdftk `ls | sort -n` cat output combinewd2.pdf
たとえば、ファイル名が 100、2、9、3.14、10、1 の場合、コマンドは次のようになります。
pdftk 1 2 3.14 9 10 100 cat output combinewd2.pdf
スペースまたはその他の特殊文字を含むファイル名を処理するには、@ joeytwiddle の優れた回答のこの修正バージョンを検討してください (数値でソートされません。以下の説明を参照してください)。
#-- 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 "$@" cat output combinewd2.pdf' "$0"
xargs
は外部コマンドです。前の例では、それを呼び出しsh
、次に を呼び出しますpdftk
。
別の方法として、可能な場合はビルトインを使用するmapfile
か、位置パラメータを使用します。次の例では、2 つの関数を使用しています。print0_filesは NUL で終了するファイル名を生成し、create_pdfは呼び出しますpdftk
。
print0_files | create_pdf combinewd2.pdf
関数は次のように定義されます
#-- 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 -- "$@" "$f"; done
pdftk "$@" cat output "$pdf"
}
コメントで指摘されているように、単純な最初の答えは、スペースやその他の特殊文字を含むファイル名では機能しません。@joeytwiddle による回答は特殊文字を処理しますが、数値的にはソートされません
#-- 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 "$@" cat output combinewd2.pdf' "$0"
コマンド ./
によって各ファイル名の前に が付けられるため、数値順にソートされません。プレフィックスを含まないコマンド サポートの一部のバージョン。より簡単で移植可能な修正は、比較で空白と英数字のみを考慮するようにコマンドにオプションを追加することですが、それでも間違った順序が生成される可能性がありますfind
find
-printf '%P\0'
./
-d, --dictionary-order
sort
#-- 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 "$@" cat output combinewd2.pdf' "$0"
ファイル名に小数が含まれていると、数値の並べ替えが正しく行われない可能性があります。このsort
コマンドは、ソート時にフィールドへのオフセットを許可します。sort -k1.3n
ただし、ファイル名をできるだけ一般的なものにする場合は、フィールド区切り記号の定義に注意する必要があります。幸いなことにsort -t '\0'
、フィールド区切り記号として NUL を指定し、find -print0
オプションは NUL を使用することを示します。をファイル名間の区切り文字として使用するためsort -z -t '\0'
、レコード区切り文字とフィールド区切り文字の両方として NUL を指定します。これにより、各ファイル名は単一のフィールド レコードになります。./
そのため、最初のフィールドの 3 番目の文字を数値ソートの開始位置として指定することで、1 つのフィールドにオフセットし、接頭辞をスキップできますsort -k1.3n -z -t '\0'
。
見苦しいですが、次のようにasでsh -c
渡された引数のリストを実行してアクセスできます。xargs
"${@}"
ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "${0}"
マンページ"${0}"
にあるように、最後に余分なものがありますsh
-c 文字列
-cオプションが存在する場合、コマンドはstringから読み取られます。stringの後に引数がある場合、それらは$0から始まる位置パラメータに割り当てられます。
これをテストするために、最初に、他のほとんどのソリューションを混乱させる複雑な名前のファイルをいくつか作成しましょう。
$ 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
すべての引数が正しく引用されています。ファイル名に改行が含まれている場合、これは失敗することに注意してください。これls -v
は基本的にls | sort -n
.
これは、スペース、改行、アポストロフィ、および引用符を含むファイル名で機能するはずです (これらはすべて UNIX ファイルシステムで可能です)。
find . -maxdepth 1 -type f -print0 |
sort -zn |
xargs -0 sh -c 'pdftk "$@" cat output combinewd2.pdf' "$0"
単純なファイル名で作業していることがわかっている場合、これは受け入れられた回答と比較してやり過ぎかもしれません。
しかし、将来再び使用されるスクリプトを作成している場合は、異常な (しかし有効な) 入力に遭遇したときに爆発しないことが望ましいです。
これは基本的に、入力ファイルを改行ではなくゼロバイトで終了するandrewdotnの回答の適応であるため、1 つ以上の改行文字を含むファイル名を保持します。
それぞれのオプション-print0
、-z
および-0
は、入力/出力をゼロバイトで区切る必要があることを各プログラムに伝えます。3 つの異なるプログラム、3 つの異なる引数!
私が見つけた最も直感的な方法は次のとおりです。
拡張子の名前を「.txt」から「.txt.json」に変更する例を次に示します。
find .|grep txt$|xargs -I{} echo "mv {} {}.json"|bash
.txt を .json に名前変更する少し高度な例 (.txt 拡張子を削除)
find $PWD|grep txt$|cut -d"." -f1|xargs -I{} echo "mv {}.txt {}.json"|bash
すべてのファイルに「End of File」という文字列を追加する必要があったことがあります。
find .|grep txt|xargs -I{} echo "echo End of File >> {}"|bash
正しく実行すれば、xargs はすべてのコマンドの王様です!
これを行うには、xargs への 2 つの呼び出しをチェーンします。echo
次のように、最初の引数を使用してすべての引数を 1 つの文字列にチェーンし、それを param として に渡し-I
ます。
ls | sort -n | xargs echo | xargs -I {} pdftk {} cat output combinewd2.pdf