GNU/Linux >> Znalost Linux >  >> Linux

Jak mohu předat všechny argumenty s xargs uprostřed příkazu v linuxu

Použijte -I možnost:

echo prefix | xargs -I % echo % post

Výstup:

prefix post

Toto je jeden způsob, jak to udělat

pdftk $(ls | sort -n) cat output combinewd2.pdf

nebo pomocí backtick

pdftk `ls | sort -n` cat output combinewd2.pdf

Pokud jsou například názvy souborů 100, 2, 9, 3.14, 10, 1, příkaz bude

pdftk 1 2 3.14 9 10 100 cat output combinewd2.pdf

Chcete-li zpracovávat názvy souborů s mezerami nebo jinými speciálními znaky, zvažte to opraveno verze @joeytwiddle vynikající odpověď (která neřadí číselně, viz diskuze níže):

#-- 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"

Alternativy k xargs (specifické pro bash)

xargs je externí příkaz, v předchozím příkladu vyvolává sh což zase vyvolá pdftk .

Alternativou je použití vestavěného mapfile pokud jsou k dispozici, nebo použijte poziční parametry. Následující příklady používají dvě funkce, print0_files vygeneruje názvy souborů ukončené NUL a create_pdf vyvolá pdftk :

print0_files | create_pdf combinewd2.pdf

Funkce jsou definovány následovně

#-- 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"
}

Diskuse

Jak bylo uvedeno v komentářích, jednoduchá počáteční odpověď nefunguje s názvy souborů obsahujícími mezery nebo jiné speciální znaky. Odpověď od @joeytwiddle zpracovává speciální znaky, i když neřadí číselně

#-- 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"

Neřadí se číselně, protože každý název souboru má předponu ./ podle find příkaz. Některé verze find podpora příkazů -printf '%P\0' který by nezahrnoval ./ předpona. Jednodušší, přenosná oprava je přidat -d, --dictionary-order možnost sort příkaz, takže při porovnávání bere v úvahu pouze prázdná místa a alfanumerické znaky, ale přesto může způsobit nesprávné řazení

#-- 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"

Pokud názvy souborů obsahují desetinná místa, mohlo by to vést k nesprávnému číselnému řazení. sort příkaz umožňuje posun do pole při řazení, sort -k1.3n , musíme být opatrní při definování oddělovače polí, pokud mají být názvy souborů co nejobecnější, naštěstí sort -t '\0' specifikuje NUL jako oddělovač polí a find -print0 volba znamená, že jako oddělovač mezi názvy souborů má být použito NUL, takže sort -z -t '\0' určuje NUL jako oddělovač záznamu i jako oddělovač pole-- každý název souboru je pak záznamem jednoho pole. Vzhledem k tomu pak můžeme offsetovat do jediného pole a přeskočit ./ prefix zadáním 3. znaku 1. pole jako počáteční pozice pro číselné řazení, sort -k1.3n -z -t '\0' .


To by mělo fungovat u názvů souborů obsahujících mezery, nové řádky, apostrofy a uvozovky (všechny jsou možné na souborových systémech UNIX):

find . -maxdepth 1 -type f -print0 |
  sort -zn |
  xargs -0 sh -c 'pdftk "[email protected]" cat output combinewd2.pdf' "$0"

To by mohlo být přehnané ve srovnání s přijatou odpovědí, pokud víte, že pracujete s jednoduchými názvy souborů.

Pokud ale píšete skript, který bude v budoucnu znovu použit, je žádoucí, aby jednoho dne nevybuchl, když se setká s neobvyklými (ale platnými) vstupy.

Toto je v podstatě adaptace andrewdotnovy odpovědi, která ukončuje vstupní soubory nulovým bajtem, namísto novým řádkem, takže zachovává názvy souborů, které obsahují jeden nebo více znaků nového řádku.

Příslušné možnosti -print0 , -z a -0 sdělte každému z programů, že vstup/výstup by měl být ohraničen nulovým bytem. Tři různé programy, tři různé argumenty!


Je to ošklivé, ale můžete spustit sh -c a přístup k seznamu argumentů předávaných xargs jako "${@}" , asi takhle:

ls | sort -n | xargs -d'\n' sh -c 'pdftk "${@}" cat output combinewd2.pdf' "${0}"

Další "${0}" na konci je tam, protože jako sh manuálová stránka říká

-c řetězec

Pokud -c je přítomna volba, pak se příkazy čtou z řetězce . Pokud jsou za řetězcem argumenty , jsou přiřazeny k pozičním parametrům počínaje $0 .

Chcete-li to otestovat, nejprve vytvořte několik souborů se složitými názvy, které naruší většinu ostatních řešení:

$ 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

Všechny argumenty jsou citovány správně. Všimněte si, že toto selže, pokud některé názvy souborů obsahují nové řádky, a že ls -v je v podstatě ls | sort -n .


Linux
  1. Jak předat heslo příkazu SCP v Linuxu

  2. Jak mohu přesouvat soubory pomocí xargs v Linuxu?

  3. Jak předat výstup příkazu jako několik argumentů jinému příkazu

  1. Příkaz Linux DD – 15 příkladů se všemi možnostmi

  2. Třídit příkaz v Linuxu s příklady

  3. Jak mohu spustit jiný příkaz, ale se stejnými argumenty?

  1. Linux řazení příkazů s příklady

  2. Jak používat příkaz IP v Linuxu s příklady

  3. Jak mohu uvést seznam všech zamčených uživatelů v Linuxu?