Bash/Klammerexpansion: Unterschied zwischen den Versionen
K Textersetzung - „== Syntax ==“ durch „== Aufruf ==“ |
|||
(47 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
'''topic''' | '''topic''' - Beschreibung | ||
'''Bash/Klammerexpansion''' (Brace expansion) is a useful technique to generate lists of strings that can be used in scripts and aliases and on the Linux command line. | |||
== Beschreibung == | == Beschreibung == | ||
* Bash ''brace expansion'' is used to generate stings at the command line or in a shell script. | |||
* Mit Hilfe der Klammererweiterung lassen sich beliebige Zeichenketten generieren. | |||
* Save time and avoid mistakes by typing less. Brасe exраnsiоn is а wаy by whiсh аrbitrаry strings саn be generаted frоm the terminаl оr by using any bаsh sсriрt | |||
** it allows you to create multiple modified command-line arguments out of a single argument. | |||
** The syntаx fоr brасe exраnsiоn соnsists оf either a '''sequenсe sрeсifiсаtiоn''' оr а '''cоmmа seраrаted list''' оf dаtа inside сurly brасes “{}”. The раttern shоuld nоt cоntаin embedded whitesрасe. | |||
** There are two optional parts to Brace expansion — '''Preamble''' and''' Postscript. '''The Preamble is prefixed to each string contained within the braces, and the Postscript is then appended to each resulting string, '''expanding left to right.''' | |||
== Installation == | == Installation == | ||
== | == Anwendung == | ||
== | The syntax for brace expansion consists of either a sequence specification or a comma separated list of items inside curly braces "{}". | ||
A sequence consists of a starting and ending item separated by two periods "..". | |||
Some examples and what they expand to: | |||
{aa,bb,cc,dd} => aa bb cc dd | |||
{0..12} => 0 1 2 3 4 5 6 7 8 9 10 11 12 | |||
{3..-2} => 3 2 1 0 -1 -2 | |||
{a..g} => a b c d e f g | |||
{g..a} => g f e d c b a | |||
If the brace expansion has a prefix or suffix string then those strings are included in the expansion: | |||
a{0..3}b => a0b a1b a2b a3b | |||
Brace expansions can be nested: | |||
{a,b{1..3},c} => a b1 b2 b3 c | |||
Counted loops in bash can be implemented a number of ways without brace expansion: | |||
# Three expression for loop: | |||
for (( i = 0; i < 20; i++ )) | |||
do | |||
echo $i | |||
done | |||
# While loop: | |||
i=0 | |||
while [[ $i -lt 20 ]] | |||
do | |||
echo $i | |||
let i++ | |||
done | |||
# For loop using seq: | |||
for i in $(seq 0 19) | |||
do | |||
echo $i | |||
done | |||
A counted for loop using bash sequences requires the least amount of typing: | |||
for i in {0..19} | |||
do | |||
echo $i | |||
done | |||
But beyond counted for loops, brace expansion is the only way to create a loop with non-numeric "indexes": | |||
for i in {a..z} | |||
do | |||
echo $i | |||
done | |||
Brace expansion can also be useful when passing multiple long pathnames to a command. | |||
* Instead of | |||
# rm /a/long/path/foo /a/long/path/bar | |||
You can simply do | |||
# rm /a/long/path/{foo,bar} | |||
Brace expansion is enabled via the "<tt>set -B</tt>" command and the "<tt>-B</tt>" command line option to the shell and disabled via "<tt>set +B</tt>" and "<tt>+B</tt>" on the command line. | |||
Q: https://www.linuxjournal.com/content/bash-brace-expansion | |||
== Aufruf == | |||
{string1,string2,...,stringN} | |||
{<START>..<END>} | |||
{<START>..<END>..<INCR>} (Bash 4) | |||
<PREFIX>{........} | |||
{........}<SUFFIX> | |||
<PREFIX>{........}<SUFFIX> | |||
=== Optionen === | === Optionen === | ||
=== Parameter === | === Parameter === | ||
=== | === Umgebung === | ||
=== | === Rückgabewert === | ||
== Konfiguration == | == Konfiguration == | ||
=== Dateien === | === Dateien === | ||
Zeile 13: | Zeile 90: | ||
== Dokumentation == | == Dokumentation == | ||
=== RFC === | === RFC === | ||
=== Man- | === Man-Page === | ||
=== Info-Pages === | === Info-Pages === | ||
== Siehe auch == | == Siehe auch == | ||
== Links == | == Links == | ||
=== Projekt | === Projekt === | ||
=== Weblinks === | === Weblinks === | ||
# [https://wiki.bash-hackers.org/syntax/expansion/intro Introduction to expansion and substitution] | |||
[[Kategorie:Bash/Expansionen]] | |||
= TMP = | = TMP = | ||
=== Brace expansion === | |||
==== Using Comma-separated lists ==== | |||
echo {geeks,for,geeks} | |||
echo {"hello","world"} | |||
==== Using Ranges ==== | |||
* Different types of ranges can be used, like numeric, alphabetic, or both. | |||
* A sequence consists of a starting and ending term separated by 2 periods “..” inside curly braces “{}”. | |||
echo {A..D} | |||
echo {3..8} | |||
echo {A..C}{1..2} | |||
==== Using Preamble ==== | |||
* Patterns to be brace expanded may contain a leading term called a preamble. | |||
* The brace expression may contain either a comma-separated list or a range | |||
echo gfg{1..4} | |||
echo gfg{1,5,9} | |||
==== Using Postscript ==== | |||
Like Preamble, it can also have an ending portion known as Postscript | |||
echo {1..3}gfg | |||
echo {1,5,9}gfg | |||
Bash Expansion can be '''nested.''' | |||
echo {a,b{1..3},c} | |||
Bash Expansion can be used with other commands also, like, we can make multiple folders with one command using Brace expansion with mkdir command. | |||
Q: [https://www.geeksforgeeks.org/bash-brace-expansion-in-linux-with-examples/ https://www.geeksforgeeks.org/bash-brace-expansion-in-linux-with-examples/] | |||
== Brace expansion == | |||
Bash uses brace expansion to generate a sequence of strings from the terminal or by using any bash script. | |||
* A sequence of expressions or comma-separated list of data with curly brackets is used to define brace expansion. | |||
* Two optional parts of brace expansion are '''preamble''' and '''postscript'''. | |||
* The '''preamble''' is used to add text at the front of each generated string and '''postscript''' is used to append text at the end of the generated string by using brace expansion. | |||
* How the user can create different types of random strings using bash brace expansion is explained in this tutorial by using various examples. | |||
=== String List === | |||
{String1, String2,... ,StringN }# Range List | |||
{<start> . . <end>}# Preamble and postscript | |||
<preamble>{ string or range }{ string or range }<postscript><preamble{ string or range }<postscript> | |||
The above syntax shows that you can use brace expansion without preamble and postscript or with preamble or with postscript or with both. | |||
* Different uses of brace expansions are shown in the next part of this tutorial by using various examples. | |||
=== Using comma-separated lists === | |||
The following command shows the use of brace expansion with comma-separated list only. | |||
* You have to remember one thing while defining the list. | |||
* That is, list items must be separated by comma only and don’t add any space between the items, otherwise brace expansion will not work. | |||
* Here, the first command will display the list items with space. | |||
* Two lists are used in the second command and the output will generate by combining each items of each list. | |||
$ echo {PHP,Javascript,JQuery}$ echo {"I like ","Learn "}{"PHP","Programming"} | |||
'''Output:''' | |||
The following output will appear after running the script. | |||
* In the second command, there are two items in each list and there are two lists. | |||
* So, the second command will print (2X2=4), four text as output. | |||
=== Using Ranges === | |||
Different types of ranges can be used in brace expansion to generate the list of data. | |||
* The uses of four types of ranges are shown in this example. | |||
* The first range will create a list of numeric data, starting from 50 to 60. | |||
* The second range will generate a list of alphabetic characters, starting from A to F. | |||
* The third range will generate a list of number, starting from 1 to 5 with leading zero. | |||
* The forth range will generate a list of alpha-numeric data by combining A to C and 1 to 3. | |||
$ echo {50..60}$ echo {A..E}$ echo {01..05}$ echo {A..C}{1..3} | |||
'''Output:''' | |||
The following output will appear after running the above commands. | |||
* In the last command, the first brace expansion contains three items and the second brace expansion contains three items. | |||
* So, the total items in the output will be, 3X3 = 9. | |||
=== Using preamble === | |||
This example shows the use of preamble in brace expansion. | |||
* The first command will add the string, '''“Hi “''' with each item of the list and generate the output. | |||
* The second command will add ‘b’ with each item of the list. | |||
* This type of task is beneficial if you want to add a common text or character at the front of each list item. | |||
$ echo "Hi "{John, Mohammed, Lisa}$ echo b{all, ell, oat, eef} | |||
'''Output''' | |||
The following output will appear after running the commands. | |||
=== Using postscript === | |||
This example shows the use of postscript in brace expansion. | |||
* The text, '''“ is a programmer”''' will add at the end of each list item in the first command. | |||
* The word, “ball” will add with each item of the list in the second command. | |||
* If the last part of each item of the list are same then it is better to create the list by brace expansion with postscript. | |||
$ echo {John,Mohammed,Lisa}" is a programmer."$ echo {basket,foot,volley}ball | |||
'''Output:''' | |||
The following output will appear after running the commands. | |||
=== Using both preamble and postscript === | |||
When the first part and last part of each item of the list are same then it better to create the list by using brace expansion with preamble and postscript. | |||
* Here, the first command will add “Hi “, at the beginning of each list item and “ welcome to LinuxHint.“, at the end of the each list item. | |||
* The second command will generate an alpha-numeric list by adding “*****” at the front and “.*****” at the end of the list item. | |||
* According to the range, the first item is Q01 and the last item is Q05. | |||
$ echo "Hi, "{John,Mohammed,Lisa}" welcome to LinuxHint."$ echo "*****Q"{01..05}".*****" | |||
'''Output:''' | |||
The following output will appear after running the commands. | |||
===Creating sequence of directory and file === | |||
'''`echo`''' command is used in all previous examples of this tutorial. | |||
* But you can use brace expansion with other commands also. | |||
* How you can create multiple files or folders in a single command by using brace expansion is shown in this tutorial. | |||
* The following command will create three folders, '''Design, Programming and Framework''', by using `'''mkdir'''` command and brace expansion. | |||
$ mkdir {Design,Programming,Framework}$ ls | |||
'''Output:''' | |||
The following output will appear after running the commands. | |||
You can also create sequential multiple files by using touch and brace expansion with preamble and postscript. | |||
* In this example''', `touch`''' command is used to create multiple files. '''“ps”''' is used as preamble, '''“.py”''' is used as postscript and '''1..3''' range is used to create the sequential file names. | |||
* The second command, ‘ls’ will show the files are created or not. | |||
$ touch “ps”{1..3}”.py” | |||
$ ls | |||
'''Output''' | |||
The following output will appear after running the commands. | |||
* Here, three files will be created. | |||
* These are '''ps1.py, ps2.py and ps3.py'''. | |||
=== Conclusion === | |||
Brace expansion is very useful for generating a list of sequential data or running any command on sequence of data. | |||
* Some common uses of brace expansion are shown in this tutorial. | |||
* Hope, the reader will be able to use brace expansion properly after practicing the examples of this tutorial. | |||
Q: [https://linuxhint.com/bash_brace_expansion/ https://linuxhint.com/bash_brace_expansion/] | |||
== Brace expansion == | |||
Brace expansion is used to generate arbitrary strings. | |||
* The specified strings are used to generate '''all possible combinations''' with the optional surrounding prefixes and suffixes. | |||
Usually it's used to generate mass-arguments for a command, that follow a specific naming-scheme. | |||
It is the very first step in expansion-handling, it's important to understand that. | |||
=== When you use === | |||
echo {a,b}$PATH | |||
then the brace expansion '''does not expand the variable''' - this is done in a '''later step'''. | |||
=== Brace expansion just makes it being: === | |||
echo a$PATH b$PATH | |||
=== Another common pitfall is to assume that a range like <tt>{1..200}</tt> can be expressed with variables using <tt>{$a..$b}</tt>. === | |||
* Due to what I described above, it '''simply is not possible''', because it's the very first step in doing expansions. | |||
* A possible way to achieve this, if you really can't handle this in another way, is using the <tt>eval</tt> command, which basically evaluates a commandline twice: | |||
eval echo {$a..$b} | |||
For instance, when embedded inside a for loop : | |||
for i in $(eval echo {$a..$b}) | |||
This requires that the entire command be properly escaped to avoid unexpected expansions. | |||
* If the sequence expansion is to be assigned to an array, another method is possible using [https://wiki.bash-hackers.org/commands/builtin/declare declaration commands]: | |||
declare -a 'pics=(img{'"$a..$b"'}.png)'; mv "${pics[@]}" ../imgs | |||
This is significantly safer, but one must still be careful to control the values of $a and $b. | |||
* Both the exact quoting, and explicitly including "-a" are important. | |||
The brace expansion is present in two basic forms, '''string lists''' and '''ranges'''. | |||
It can be switched on and off under runtime by using the <tt>set</tt> builtin and the option <tt>-B</tt> and <tt>+B</tt> or the long option <tt>braceexpand</tt>. | |||
* If brace expansion is enabled, the stringlist in <tt>SHELLOPTS</tt> contains <tt>braceexpand</tt>. | |||
=== String lists === | |||
{string1,string2,...,stringN} | |||
Without the optional prefix and suffix strings, the result is just a space-separated list of the given strings: | |||
$ echo {I,want,my,money,back} | |||
I want my money back | |||
With prefix or suffix strings, the result is a space-separated list of '''all possible combinations''' of prefix or suffix specified strings: | |||
$ echo _{I,want,my,money,back} | |||
_I _want _my _money _back | |||
$ echo {I,want,my,money,back}_ | |||
I_ want_ my_ money_ back_ | |||
$ echo _{I,want,my,money,back}- | |||
_I- _want- _my- _money- _back- | |||
The brace expansion is only performed, if the given string list is really a '''list of strings''', i.e., if there is a minimum of one "<tt>,</tt>" (comma)! Something like <tt>{money}</tt> doesn't expand to something special, it's really only the text "<tt>{money}</tt>". | |||
=== Ranges === | |||
{<START>..<END>} | |||
Brace expansion using ranges is written giving the startpoint and the endpoint of the range. | |||
* This is a "sequence expression". | |||
* The sequences can be of two types * integers (optionally zero padded, optionally with a given increment) | |||
* characters | |||
$ echo {5..12} | |||
5 6 7 8 9 10 11 12 | |||
$ echo {c..k} | |||
c d e f g h i j k | |||
When you mix these both types, brace expansion is '''not''' performed: | |||
$ echo {5..k} | |||
{5..k} | |||
When you zero pad one of the numbers (or both) in a range, then the generated range is zero padded, too: | |||
$ echo {01..10} | |||
01 02 03 04 05 06 07 08 09 10 | |||
There's a chapter of Bash 4 brace expansion changes at [https://wiki.bash-hackers.org/syntax/expansion/brace#new_in_bash_40 the end of this article]. | |||
Similar to the expansion using stringlists, you can add prefix and suffix strings: | |||
$ echo 1.{0..9} | |||
1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 | |||
$ echo ---{A..E}--- | |||
---A--- ---B--- ---C--- ---D--- ---E--- | |||
=== Combining and nesting === | |||
When you combine more brace expansions, you effectively use a brace expansion as prefix or suffix for another one. | |||
* Let's generate all possible combinations of uppercase letters and digits: | |||
$ echo {A..Z}{0..9} | |||
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 C0 C1 C2 C3 C4 C5 C6 | |||
C7 C8 C9 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 F0 F1 F2 F3 | |||
F4 F5 F6 F7 F8 F9 G0 G1 G2 G3 G4 G5 G6 G7 G8 G9 H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 I0 | |||
I1 I2 I3 I4 I5 I6 I7 I8 I9 J0 J1 J2 J3 J4 J5 J6 J7 J8 J9 K0 K1 K2 K3 K4 K5 K6 K7 | |||
K8 K9 L0 L1 L2 L3 L4 L5 L6 L7 L8 L9 M0 M1 M2 M3 M4 M5 M6 M7 M8 M9 N0 N1 N2 N3 N4 | |||
N5 N6 N7 N8 N9 O0 O1 O2 O3 O4 O5 O6 O7 O8 O9 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 Q0 Q1 | |||
Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 S0 S1 S2 S3 S4 S5 S6 S7 S8 | |||
S9 T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 U0 U1 U2 U3 U4 U5 U6 U7 U8 U9 V0 V1 V2 V3 V4 V5 | |||
V6 V7 V8 V9 W0 W1 W2 W3 W4 W5 W6 W7 W8 W9 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 Y0 Y1 Y2 | |||
Y3 Y4 Y5 Y6 Y7 Y8 Y9 Z0 Z1 Z2 Z3 Z4 Z5 Z6 Z7 Z8 Z9 | |||
* that '''saves you writing''' 260 strings | |||
Brace expansions can be nested, but too much of it usually makes you losing overview a bit | |||
Here's a sample to generate the alphabet, first the uppercase letters, then the lowercase ones: | |||
$ echo {{A..Z},{a..z}} | |||
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z | |||
=== Common use and examples === | |||
==== Massdownload from the Web ==== | |||
In this example, <tt>wget</tt> is used to download documentation that is split over several numbered webpages. | |||
<tt>wget</tt> won't see your braces. | |||
* It will see '''6 different URLs''' to download. | |||
wget http://docs.example.com/documentation/slides_part{1,2,3,4,5,6}.html | |||
It's possible, and even easier, to do that with a sequence: | |||
wget http://docs.example.com/documentation/slides_part{1..6}.html | |||
==== Generate a subdirectory structure ==== | |||
Your life is hard? Let's ease it a bit - that's what shells are here for. | |||
mkdir /home/bash/test/{foo,bar,baz,cat,dog} | |||
==== Generate numbers with a prefix 001 002 ... ==== | |||
Using a prefix: | |||
for i in 0{1..9} 10; do printf "%s\n" "$i";done | |||
If you need to create words with the number embedded, you can use nested brace: | |||
printf "%s\n" img{00{1..9},0{10..99},{100..999}}.png* Formatting the numbers with printf: | |||
echo $(printf "img%02d.png " {1..99}) | |||
See the [https://wiki.bash-hackers.org/syntax/expansion/brace#news_in_bash_40 text below] for a new Bash 4 method. | |||
==== Repeating arguments or words ==== | |||
somecommand -v -v -v -v -v | |||
Can be written as | |||
somecommand -v{,,,,} | |||
…which is a kind of a hack, but hey, it works. | |||
===== More fun ===== | |||
The most optimal possible brace expansion to expand n arguments of course consists of n's prime factors. | |||
* We can use the "factor" program bundled with GNU coreutils to emit a brace expansion that will expand any number of arguments. | |||
function braceify { | |||
[[ $1 == +([[:digit:]]) ]] || return | |||
typeset -a a | |||
read -ra a < <(factor "$1") | |||
eval "echo $(printf '{$(printf ,%%.s {1..%s})}' "${a[@]:1}")" | |||
} | |||
printf 'eval printf "$arg"%s' "$(braceify 1000000)" | |||
"Braceify" generates the expansion code itself. | |||
* In this example we inject that output into a template which displays the most terse brace expansion code that would expand <tt>"$arg"</tt> 1,000,000 times if evaluated. | |||
* In this case, the output is: | |||
eval printf "$arg"{,,}{,,}{,,}{,,}{,,}{,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,} | |||
=== Zero padded number expansion === | |||
* New in Bash 4.0 | |||
* Prefix either of the numbers in a numeric range with <tt>0</tt> to pad the expanded numbers with the correct amount of zeros: | |||
$ echo {0001..5} | |||
0001 0002 0003 0004 0005 | |||
==== Increment ==== | |||
It is now possible to specify an increment using ranges: | |||
{<START>..<END>..<INCR>} | |||
<tt><INCR></tt> is numeric, you can use a negative integer but the correct sign is deduced from the order of <tt><START></tt> and <tt><END></tt> anyways. | |||
$ echo {1..10..2} | |||
1 3 5 7 9 | |||
$ echo {10..1..2} | |||
10 8 6 4 2 | |||
Interesting feature: The increment specification also works for letter-ranges: | |||
$ echo {a..z..3} | |||
a d g j m p s v y | |||
== Use Brace Expansion == | |||
=== Brace Expansion === | |||
Before the Bash shell [https://man7.org/linux/man-pages/man1/bash.1.html executes a command] in a terminal window or a line in a script, it checks whether it needs to perform any substitutions on the command. | |||
* Variable names are replaced by their values, aliases are replaced by the commands they’re shorthand for, and any expansion is performed. | |||
* Brace expansion is one form of expansion supported by Bash. | |||
Brace expansion is available in modern shells, but it might be missing from some old shells. | |||
* If you’re going to use brace expansion in scripts, make sure that you invoke a shell that supports brace expansion, such as Bash/ | |||
#!/bin/bash | |||
We’ll be using Bash for our examples. | |||
Generating lists of strings might seem more of a novelty than a benefit, but it does offer some functionality that can save time and keystrokes. | |||
* Often, it can provide a simple and elegant solution to a problem or requirement. | |||
=== Simple Expansions === | |||
A brace expansion is contained between a pair of braces “{}”. | |||
* It can be a list of comma-separated items or a range specifier. | |||
* Spaces are not permitted inside the braces unless you’ve wrapped the string in quotation marks “<tt>"</tt>.” | |||
For a comma-separated list, the expansion process takes each element in turn and passes it to the calling command. | |||
* In this example, it’s <tt>echo</tt> that simply [https://www.howtogeek.com/446071/how-to-use-the-echo-command-on-linux/ prints them in the terminal window]. | |||
* Note that the commas are ignored. | |||
echo {one,two,three,four} | |||
A list can be words or digits. | |||
echo {1,2,3,4} | |||
The order of the list elements is completely arbitrary. | |||
echo (4,2,3,1) | |||
An expansion range has a start and an end character connected with two periods ” <tt>..</tt> ” without any whitespace. | |||
* All of the missing list elements are provided automatically by the expansion so that the entire range from start character to end character is created. | |||
This will print the digits from 1 to 10. | |||
The Best Tech Newsletter Anywhere | |||
Join '''425,000''' subscribers and get a daily digest of features, articles, news, and trivia. | |||
By submitting your email, you agree to the [https://www.howtogeek.com/terms-of-use Terms of Use] and [https://www.howtogeek.com/privacy-policy Privacy Policy]. | |||
echo {1..10} | |||
The numbering is arbitrary. | |||
* It does not have to start at one. | |||
echo {3..12} | |||
Ranges can be specified so that they run backward. | |||
* This will generate a list from five down to one. | |||
echo {5..1} | |||
Ranges can include negative numbers. | |||
echo {4..-4} | |||
As we previously pointed out, a range has a start and an end ''character''. | |||
* It doesn’t have to be a number. | |||
* It can be a letter. | |||
echo {q..v} | |||
The letters can run backward, too. | |||
echo {f..a} | |||
=== Using Brace Expansion with Loops === | |||
You can use brace expansion with ranges in loops in scripts. | |||
for i in {3..7} | |||
do | |||
echo $i | |||
done | |||
Brace expansion ranges let you use characters as the loop variable. | |||
for i in {m..q} | |||
do | |||
echo $i | |||
done | |||
Loops are usually used in scripts, but there’s nothing to stop you from typing them into the command line to see what will happen. | |||
for i in {3..7}; do echo $i; done | |||
for i in {m..q}; do echo $i; done | |||
=== Concatenating and Nesting === | |||
Two adjacent expansions don’t act independently one after the other. | |||
* They interoperate. | |||
* Each element in the first expansion is acted on by each element in the second expansion. | |||
echo {q..v}{1..3} | |||
Expansions can also be nested. | |||
* A nested expansion will act on the element immediately preceding it. | |||
echo {part-1,part-2{a,b,c,d},part-3} | |||
[https://www.howtogeek.com/725657/how-to-use-brace-expansion-in-linuxs-bash-shell/#skip-to-div-bordeaux-static-slot-17 Skip advert]You can also nest expansions by creating a comma-delimited list of range expansions. | |||
echo {{5..0},{1..5}} | |||
=== Preamble and Postscript === | |||
You can place text before and after a brace expansion to have that text included in the results of the expansion. | |||
* Text put in front of an expansion is called the preamble, while text placed behind a brace expansion is called the postscript. | |||
This command uses a preamble. | |||
echo chapter{1..3} | |||
This example uses a postscript: | |||
echo {contents,paper,bilbiography}.md | |||
And this command uses both. | |||
echo chapter-{1..4}.md | |||
=== Expanding File Names and Directories === | |||
As you’ve probably guessed by now, one of the main uses of brace expansions is to create file and directory names that can be passed to other commands. | |||
* We’ve been using <tt>echo</tt> as a convenient way to see exactly what happens when an expansion is triggered. | |||
* You can substitute any command that takes filenames or directory names as input and use brace expansion with it. | |||
To quickly [https://www.howtogeek.com/199687/how-to-quickly-create-a-text-file-using-the-command-line-in-linux/ create some files], use <tt>touch</tt>: | |||
touch file-{1..4}.txt | |||
ls *.txt | |||
If you have many files with the same base name but different file extensions and you want to perform an operation on a subset of them, brace expansions can help. | |||
* Here, we’re compressing a subset of files that have “program” as the basename into a ZIP file called “source-code.zip.” | |||
Development directories contain lots of files that will have the same basename as your main program. | |||
* Usually, you don’t want to back up or distribute files like “.o” object files. | |||
* This is a neat way to only include the file types of interest. | |||
zip source-code program{.c,.h,.css} | |||
This command will make a copy of a file and append “.bak” to it, making a backup copy of the original file. | |||
* An interesting point to note is that the brace expansion contains a comma-separated list, but the first element is empty. | |||
* If we hadn’t included the comma, the expansion wouldn’t have taken place. | |||
cp brace/new/prog-1.c{,.bak} | |||
ls brace/new/prog-1.c.bak | |||
To perform some action on two files in different directories, we can use a brace expansion in the path to the files. | |||
In this example, the “brace” directory contains two subdirectories, one called “new” and one called “old.” They contain different versions of the same set of source code files. | |||
* We’ll use the <tt>diff</tt> program to see the differences between the two versions of “prog-1.c.” | |||
diff brace/{new,old}/prog-1.c | |||
If you have a standard skeleton of directories that you need to create at the start of a project, you can create them quickly using brace expansion. | |||
* The <tt>mkdir</tt> <tt>-p</tt> (parent) option [https://man7.org/linux/man-pages/man1/mkdir.1.html creates any missing parent directories] when a child directory is created. | |||
mkdir -p {source,build,man,help{/pages,/yelp,/images}} | |||
tree | |||
You can use brace expansion with <tt>wget</tt> to [https://man7.org/linux/man-pages/man1/wget.1.html download multiple files]. | |||
In this command, we’re going to download files from two directories, called “test1” and “test2.” Each directory holds two files called “picture1” and “picture2.” | |||
wget https://www.URL-of-your-choice.com/test{1,2}/picture{001,002}.jpg | |||
Listing the files shows you the files that were retrieved and how <tt>wget</tt> renames files to avoid name clashes with existing files. | |||
ls picture*.* | |||
=== Embrace the Brace === | |||
'''RELATED'''[https://www.howtogeek.com/439199/15-special-characters-you-need-to-know-for-bash/ 15 Special Characters You Need to Know for Bash] | |||
It seems that brace expansion is another one of [https://www.howtogeek.com/439199/15-special-characters-you-need-to-know-for-bash/ Linux’s best-kept secrets]. | |||
* Many people tell me that they’ve never heard of brace expansion, while others inform me that it’s one of their favorite command-line tricks. | |||
Give it a try and it just might find its way into your set of command-line go-to tricks. | |||
=== Quelle === | |||
# https://www.howtogeek.com/725657/how-to-use-brace-expansion-in-linuxs-bash-shell/ | |||
== Brace expansion == | == Brace expansion == | ||
Zeile 55: | Zeile 633: | ||
Beispiel_1_ Beispiel_2_ Beispiel_3_ | Beispiel_1_ Beispiel_2_ Beispiel_3_ | ||
Präfix und Postfix können ihrerseits wiederum Klammererweiterungen sein und Klammererweiterungen können verschachtelt werden, sodass sich z.B. mit nur einem Befehl eine ganze Verzeichnishierarchie erzeugen lässt: | Präfix und Postfix können ihrerseits wiederum Klammererweiterungen sein und Klammererweiterungen können verschachtelt werden, sodass sich z. B. | ||
* mit nur einem Befehl eine ganze Verzeichnishierarchie erzeugen lässt: | |||
$ '''mkdir -p bsp/{ucb/{ex,edit},lib/{bla,foo}}''' | $ '''mkdir -p bsp/{ucb/{ex,edit},lib/{bla,foo}}''' | ||
Zeile 86: | Zeile 665: | ||
=== Brace expansion === | === Brace expansion === | ||
Ähnlich wie die Expansion von Dateinamen ist die Expansion von geschweiften Klammern eine kompakte Methode, um mehrere ähnliche Argumente darzustellen. | |||
Die folgenden vier Befehle sind gleichwertig: | |||
$ ls file1.txt file2.txt file3.txt file4.txt file5.txt | $ ls file1.txt file2.txt file3.txt file4.txt file5.txt | ||
$ ls file{1,2,3,4,5}.txt | $ ls file{1,2,3,4,5}.txt | ||
Zeile 94: | Zeile 673: | ||
$ file{1..5}.txt | $ file{1..5}.txt | ||
* Der erste Befehl listet jedes Argument explizit auf. | |||
* Die anderen drei Befehle verwenden alle Klammererweiterungen, um die Argumente knapper auszudrücken: | |||
* beim zweiten Befehl werden alle Möglichkeiten von 1 bis 5 angegeben, getrennt durch Kommas | |||
* beim dritten Befehl wird eine numerische Folge angegeben ("von 1 bis 5, aufsteigend um 1") | |||
* der vierte Befehl ist derselbe wie der dritte, lässt aber die ..1 implizit. | |||
Wir können die Dateien auch in der umgekehrten Reihenfolge auflisten: | |||
$ ls file5.txt file4.txt file3.txt file2.txt file1.txt | $ ls file5.txt file4.txt file3.txt file2.txt file1.txt | ||
$ ls file{5,4,3,2,1}.txt | $ ls file{5,4,3,2,1}.txt | ||
Zeile 107: | Zeile 685: | ||
$ ls file{5..1}.txt | $ ls file{5..1}.txt | ||
wobei die Standard-Inkrementgröße -1 ist, wenn der Endpunkt der Sequenz kleiner ist als der Startpunkt. | |||
Da in der Bash das erste Wort eines Befehls das Programm ist, das ausgeführt wird, könnten wir den Befehl auch so schreiben: | |||
$ {ls,file{1..5}.txt} | $ {ls,file{1..5}.txt} | ||
das ist der Lesbarkeit nicht förderlich! | |||
Dasselbe kann mit der Expansion von Dateinamen gemacht werden. | |||
Die Expansion von geschweiften Klammern kann wie die Expansion von Dateinamen durch jeden der Anführungszeichen-Mechanismen deaktiviert werden | |||
'{', "{" oder \{ | |||
erzeugt eine tatsächliche geschweifte Klammer. | |||
== Beispiel == | |||
# root@debian ~ # chown -Rc dirkwagner.dirkwagner /media/daten/{tools,kurse,ebooks} | # root@debian ~ # chown -Rc dirkwagner.dirkwagner /media/daten/{tools,kurse,ebooks} | ||
Aktuelle Version vom 12. November 2024, 18:43 Uhr
topic - Beschreibung
Bash/Klammerexpansion (Brace expansion) is a useful technique to generate lists of strings that can be used in scripts and aliases and on the Linux command line.
Beschreibung
- Bash brace expansion is used to generate stings at the command line or in a shell script.
- Mit Hilfe der Klammererweiterung lassen sich beliebige Zeichenketten generieren.
- Save time and avoid mistakes by typing less. Brасe exраnsiоn is а wаy by whiсh аrbitrаry strings саn be generаted frоm the terminаl оr by using any bаsh sсriрt
- it allows you to create multiple modified command-line arguments out of a single argument.
- The syntаx fоr brасe exраnsiоn соnsists оf either a sequenсe sрeсifiсаtiоn оr а cоmmа seраrаted list оf dаtа inside сurly brасes “{}”. The раttern shоuld nоt cоntаin embedded whitesрасe.
- There are two optional parts to Brace expansion — Preamble and Postscript. The Preamble is prefixed to each string contained within the braces, and the Postscript is then appended to each resulting string, expanding left to right.
Installation
Anwendung
The syntax for brace expansion consists of either a sequence specification or a comma separated list of items inside curly braces "{}".
A sequence consists of a starting and ending item separated by two periods "..".
Some examples and what they expand to:
{aa,bb,cc,dd} => aa bb cc dd {0..12} => 0 1 2 3 4 5 6 7 8 9 10 11 12 {3..-2} => 3 2 1 0 -1 -2 {a..g} => a b c d e f g {g..a} => g f e d c b a
If the brace expansion has a prefix or suffix string then those strings are included in the expansion:
a{0..3}b => a0b a1b a2b a3b
Brace expansions can be nested:
{a,b{1..3},c} => a b1 b2 b3 c
Counted loops in bash can be implemented a number of ways without brace expansion:
# Three expression for loop: for (( i = 0; i < 20; i++ )) do echo $i done # While loop: i=0 while $i -lt 20 do echo $i let i++ done # For loop using seq: for i in $(seq 0 19) do echo $i done
A counted for loop using bash sequences requires the least amount of typing:
for i in {0..19} do echo $i done
But beyond counted for loops, brace expansion is the only way to create a loop with non-numeric "indexes":
for i in {a..z} do echo $i done
Brace expansion can also be useful when passing multiple long pathnames to a command.
- Instead of
# rm /a/long/path/foo /a/long/path/bar
You can simply do
# rm /a/long/path/{foo,bar}
Brace expansion is enabled via the "set -B" command and the "-B" command line option to the shell and disabled via "set +B" and "+B" on the command line.
Q: https://www.linuxjournal.com/content/bash-brace-expansion
Aufruf
{string1,string2,...,stringN} {<START>..<END>} {<START>..<END>..<INCR>} (Bash 4) <PREFIX>{........} {........}<SUFFIX> <PREFIX>{........}<SUFFIX>
Optionen
Parameter
Umgebung
Rückgabewert
Konfiguration
Dateien
Sicherheit
Dokumentation
RFC
Man-Page
Info-Pages
Siehe auch
Links
Projekt
Weblinks
TMP
Brace expansion
Using Comma-separated lists
echo {geeks,for,geeks} echo {"hello","world"}
Using Ranges
- Different types of ranges can be used, like numeric, alphabetic, or both.
- A sequence consists of a starting and ending term separated by 2 periods “..” inside curly braces “{}”.
echo {A..D} echo {3..8} echo {A..C}{1..2}
Using Preamble
- Patterns to be brace expanded may contain a leading term called a preamble.
- The brace expression may contain either a comma-separated list or a range
echo gfg{1..4} echo gfg{1,5,9}
Using Postscript
Like Preamble, it can also have an ending portion known as Postscript
echo {1..3}gfg echo {1,5,9}gfg
Bash Expansion can be nested.
echo {a,b{1..3},c}
Bash Expansion can be used with other commands also, like, we can make multiple folders with one command using Brace expansion with mkdir command.
Q: https://www.geeksforgeeks.org/bash-brace-expansion-in-linux-with-examples/
Brace expansion
Bash uses brace expansion to generate a sequence of strings from the terminal or by using any bash script.
- A sequence of expressions or comma-separated list of data with curly brackets is used to define brace expansion.
- Two optional parts of brace expansion are preamble and postscript.
- The preamble is used to add text at the front of each generated string and postscript is used to append text at the end of the generated string by using brace expansion.
- How the user can create different types of random strings using bash brace expansion is explained in this tutorial by using various examples.
String List
{String1, String2,... ,StringN }# Range List {<start> . . <end>}# Preamble and postscript <preamble>{ string or range }{ string or range }<postscript><preamble{ string or range }<postscript>
The above syntax shows that you can use brace expansion without preamble and postscript or with preamble or with postscript or with both.
- Different uses of brace expansions are shown in the next part of this tutorial by using various examples.
Using comma-separated lists
The following command shows the use of brace expansion with comma-separated list only.
- You have to remember one thing while defining the list.
- That is, list items must be separated by comma only and don’t add any space between the items, otherwise brace expansion will not work.
- Here, the first command will display the list items with space.
- Two lists are used in the second command and the output will generate by combining each items of each list.
$ echo {PHP,Javascript,JQuery}$ echo {"I like ","Learn "}{"PHP","Programming"}
Output:
The following output will appear after running the script.
- In the second command, there are two items in each list and there are two lists.
- So, the second command will print (2X2=4), four text as output.
Using Ranges
Different types of ranges can be used in brace expansion to generate the list of data.
- The uses of four types of ranges are shown in this example.
- The first range will create a list of numeric data, starting from 50 to 60.
- The second range will generate a list of alphabetic characters, starting from A to F.
- The third range will generate a list of number, starting from 1 to 5 with leading zero.
- The forth range will generate a list of alpha-numeric data by combining A to C and 1 to 3.
$ echo {50..60}$ echo {A..E}$ echo {01..05}$ echo {A..C}{1..3}
Output:
The following output will appear after running the above commands.
- In the last command, the first brace expansion contains three items and the second brace expansion contains three items.
- So, the total items in the output will be, 3X3 = 9.
Using preamble
This example shows the use of preamble in brace expansion.
- The first command will add the string, “Hi “ with each item of the list and generate the output.
- The second command will add ‘b’ with each item of the list.
- This type of task is beneficial if you want to add a common text or character at the front of each list item.
$ echo "Hi "{John, Mohammed, Lisa}$ echo b{all, ell, oat, eef}
Output
The following output will appear after running the commands.
Using postscript
This example shows the use of postscript in brace expansion.
- The text, “ is a programmer” will add at the end of each list item in the first command.
- The word, “ball” will add with each item of the list in the second command.
- If the last part of each item of the list are same then it is better to create the list by brace expansion with postscript.
$ echo {John,Mohammed,Lisa}" is a programmer."$ echo {basket,foot,volley}ball
Output:
The following output will appear after running the commands.
Using both preamble and postscript
When the first part and last part of each item of the list are same then it better to create the list by using brace expansion with preamble and postscript.
- Here, the first command will add “Hi “, at the beginning of each list item and “ welcome to LinuxHint.“, at the end of the each list item.
- The second command will generate an alpha-numeric list by adding “*****” at the front and “.*****” at the end of the list item.
- According to the range, the first item is Q01 and the last item is Q05.
$ echo "Hi, "{John,Mohammed,Lisa}" welcome to LinuxHint."$ echo "*****Q"{01..05}".*****"
Output:
The following output will appear after running the commands.
Creating sequence of directory and file
`echo` command is used in all previous examples of this tutorial.
- But you can use brace expansion with other commands also.
- How you can create multiple files or folders in a single command by using brace expansion is shown in this tutorial.
- The following command will create three folders, Design, Programming and Framework, by using `mkdir` command and brace expansion.
$ mkdir {Design,Programming,Framework}$ ls
Output:
The following output will appear after running the commands.
You can also create sequential multiple files by using touch and brace expansion with preamble and postscript.
- In this example, `touch` command is used to create multiple files. “ps” is used as preamble, “.py” is used as postscript and 1..3 range is used to create the sequential file names.
- The second command, ‘ls’ will show the files are created or not.
$ touch “ps”{1..3}”.py” $ ls
Output
The following output will appear after running the commands.
- Here, three files will be created.
- These are ps1.py, ps2.py and ps3.py.
Conclusion
Brace expansion is very useful for generating a list of sequential data or running any command on sequence of data.
- Some common uses of brace expansion are shown in this tutorial.
- Hope, the reader will be able to use brace expansion properly after practicing the examples of this tutorial.
Q: https://linuxhint.com/bash_brace_expansion/
Brace expansion
Brace expansion is used to generate arbitrary strings.
- The specified strings are used to generate all possible combinations with the optional surrounding prefixes and suffixes.
Usually it's used to generate mass-arguments for a command, that follow a specific naming-scheme.
It is the very first step in expansion-handling, it's important to understand that.
When you use
echo {a,b}$PATH
then the brace expansion does not expand the variable - this is done in a later step.
Brace expansion just makes it being:
echo a$PATH b$PATH
Another common pitfall is to assume that a range like {1..200} can be expressed with variables using {$a..$b}.
- Due to what I described above, it simply is not possible, because it's the very first step in doing expansions.
- A possible way to achieve this, if you really can't handle this in another way, is using the eval command, which basically evaluates a commandline twice:
eval echo {$a..$b}
For instance, when embedded inside a for loop :
for i in $(eval echo {$a..$b})
This requires that the entire command be properly escaped to avoid unexpected expansions.
- If the sequence expansion is to be assigned to an array, another method is possible using declaration commands:
declare -a 'pics=(img{'"$a..$b"'}.png)'; mv "${pics[@]}" ../imgs
This is significantly safer, but one must still be careful to control the values of $a and $b.
- Both the exact quoting, and explicitly including "-a" are important.
The brace expansion is present in two basic forms, string lists and ranges.
It can be switched on and off under runtime by using the set builtin and the option -B and +B or the long option braceexpand.
- If brace expansion is enabled, the stringlist in SHELLOPTS contains braceexpand.
String lists
{string1,string2,...,stringN}
Without the optional prefix and suffix strings, the result is just a space-separated list of the given strings:
$ echo {I,want,my,money,back} I want my money back
With prefix or suffix strings, the result is a space-separated list of all possible combinations of prefix or suffix specified strings:
$ echo _{I,want,my,money,back} _I _want _my _money _back
$ echo {I,want,my,money,back}_ I_ want_ my_ money_ back_
$ echo _{I,want,my,money,back}- _I- _want- _my- _money- _back-
The brace expansion is only performed, if the given string list is really a list of strings, i.e., if there is a minimum of one "," (comma)! Something like {money} doesn't expand to something special, it's really only the text "{money}".
Ranges
{<START>..<END>}
Brace expansion using ranges is written giving the startpoint and the endpoint of the range.
- This is a "sequence expression".
- The sequences can be of two types * integers (optionally zero padded, optionally with a given increment)
- characters
$ echo {5..12} 5 6 7 8 9 10 11 12
$ echo {c..k} c d e f g h i j k
When you mix these both types, brace expansion is not performed:
$ echo {5..k} {5..k}
When you zero pad one of the numbers (or both) in a range, then the generated range is zero padded, too:
$ echo {01..10} 01 02 03 04 05 06 07 08 09 10
There's a chapter of Bash 4 brace expansion changes at the end of this article.
Similar to the expansion using stringlists, you can add prefix and suffix strings:
$ echo 1.{0..9} 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9
$ echo ---{A..E}--- ---A--- ---B--- ---C--- ---D--- ---E---
Combining and nesting
When you combine more brace expansions, you effectively use a brace expansion as prefix or suffix for another one.
- Let's generate all possible combinations of uppercase letters and digits:
$ echo {A..Z}{0..9} A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 G0 G1 G2 G3 G4 G5 G6 G7 G8 G9 H0 H1 H2 H3 H4 H5 H6 H7 H8 H9 I0 I1 I2 I3 I4 I5 I6 I7 I8 I9 J0 J1 J2 J3 J4 J5 J6 J7 J8 J9 K0 K1 K2 K3 K4 K5 K6 K7 K8 K9 L0 L1 L2 L3 L4 L5 L6 L7 L8 L9 M0 M1 M2 M3 M4 M5 M6 M7 M8 M9 N0 N1 N2 N3 N4 N5 N6 N7 N8 N9 O0 O1 O2 O3 O4 O5 O6 O7 O8 O9 P0 P1 P2 P3 P4 P5 P6 P7 P8 P9 Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 Q8 Q9 R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 S0 S1 S2 S3 S4 S5 S6 S7 S8 S9 T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 U0 U1 U2 U3 U4 U5 U6 U7 U8 U9 V0 V1 V2 V3 V4 V5 V6 V7 V8 V9 W0 W1 W2 W3 W4 W5 W6 W7 W8 W9 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7 Y8 Y9 Z0 Z1 Z2 Z3 Z4 Z5 Z6 Z7 Z8 Z9
- that saves you writing 260 strings
Brace expansions can be nested, but too much of it usually makes you losing overview a bit
Here's a sample to generate the alphabet, first the uppercase letters, then the lowercase ones:
$ echo {{A..Z},{a..z}} A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z
Common use and examples
Massdownload from the Web
In this example, wget is used to download documentation that is split over several numbered webpages.
wget won't see your braces.
- It will see 6 different URLs to download.
wget http://docs.example.com/documentation/slides_part{1,2,3,4,5,6}.html
It's possible, and even easier, to do that with a sequence:
wget http://docs.example.com/documentation/slides_part{1..6}.html
Generate a subdirectory structure
Your life is hard? Let's ease it a bit - that's what shells are here for.
mkdir /home/bash/test/{foo,bar,baz,cat,dog}
Generate numbers with a prefix 001 002 ...
Using a prefix:
for i in 0{1..9} 10; do printf "%s\n" "$i";done
If you need to create words with the number embedded, you can use nested brace:
printf "%s\n" img{00{1..9},0{10..99},{100..999}}.png* Formatting the numbers with printf:
echo $(printf "img%02d.png " {1..99})
See the text below for a new Bash 4 method.
Repeating arguments or words
somecommand -v -v -v -v -v
Can be written as
somecommand -v{,,,,}
…which is a kind of a hack, but hey, it works.
More fun
The most optimal possible brace expansion to expand n arguments of course consists of n's prime factors.
- We can use the "factor" program bundled with GNU coreutils to emit a brace expansion that will expand any number of arguments.
function braceify { [[ $1 == +(digit:) ]] || return typeset -a a read -ra a < <(factor "$1") eval "echo $(printf '{$(printf ,%%.s {1..%s})}' "${a[@]:1}")" }
printf 'eval printf "$arg"%s' "$(braceify 1000000)"
"Braceify" generates the expansion code itself.
- In this example we inject that output into a template which displays the most terse brace expansion code that would expand "$arg" 1,000,000 times if evaluated.
- In this case, the output is:
eval printf "$arg"{,,}{,,}{,,}{,,}{,,}{,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,}{,,,,,}
Zero padded number expansion
- New in Bash 4.0
- Prefix either of the numbers in a numeric range with 0 to pad the expanded numbers with the correct amount of zeros:
$ echo {0001..5} 0001 0002 0003 0004 0005
Increment
It is now possible to specify an increment using ranges:
{<START>..<END>..<INCR>}
<INCR> is numeric, you can use a negative integer but the correct sign is deduced from the order of <START> and <END> anyways.
$ echo {1..10..2} 1 3 5 7 9 $ echo {10..1..2} 10 8 6 4 2
Interesting feature: The increment specification also works for letter-ranges:
$ echo {a..z..3} a d g j m p s v y
Use Brace Expansion
Brace Expansion
Before the Bash shell executes a command in a terminal window or a line in a script, it checks whether it needs to perform any substitutions on the command.
- Variable names are replaced by their values, aliases are replaced by the commands they’re shorthand for, and any expansion is performed.
- Brace expansion is one form of expansion supported by Bash.
Brace expansion is available in modern shells, but it might be missing from some old shells.
- If you’re going to use brace expansion in scripts, make sure that you invoke a shell that supports brace expansion, such as Bash/
#!/bin/bash
We’ll be using Bash for our examples.
Generating lists of strings might seem more of a novelty than a benefit, but it does offer some functionality that can save time and keystrokes.
- Often, it can provide a simple and elegant solution to a problem or requirement.
Simple Expansions
A brace expansion is contained between a pair of braces “{}”.
- It can be a list of comma-separated items or a range specifier.
- Spaces are not permitted inside the braces unless you’ve wrapped the string in quotation marks “".”
For a comma-separated list, the expansion process takes each element in turn and passes it to the calling command.
- In this example, it’s echo that simply prints them in the terminal window.
- Note that the commas are ignored.
echo {one,two,three,four}
A list can be words or digits.
echo {1,2,3,4}
The order of the list elements is completely arbitrary.
echo (4,2,3,1)
An expansion range has a start and an end character connected with two periods ” .. ” without any whitespace.
- All of the missing list elements are provided automatically by the expansion so that the entire range from start character to end character is created.
This will print the digits from 1 to 10.
The Best Tech Newsletter Anywhere
Join 425,000 subscribers and get a daily digest of features, articles, news, and trivia.
By submitting your email, you agree to the Terms of Use and Privacy Policy.
echo {1..10}
The numbering is arbitrary.
- It does not have to start at one.
echo {3..12}
Ranges can be specified so that they run backward.
- This will generate a list from five down to one.
echo {5..1}
Ranges can include negative numbers.
echo {4..-4}
As we previously pointed out, a range has a start and an end character.
- It doesn’t have to be a number.
- It can be a letter.
echo {q..v}
The letters can run backward, too.
echo {f..a}
Using Brace Expansion with Loops
You can use brace expansion with ranges in loops in scripts.
for i in {3..7} do echo $i done
Brace expansion ranges let you use characters as the loop variable.
for i in {m..q} do echo $i done
Loops are usually used in scripts, but there’s nothing to stop you from typing them into the command line to see what will happen.
for i in {3..7}; do echo $i; done for i in {m..q}; do echo $i; done
Concatenating and Nesting
Two adjacent expansions don’t act independently one after the other.
- They interoperate.
- Each element in the first expansion is acted on by each element in the second expansion.
echo {q..v}{1..3}
Expansions can also be nested.
- A nested expansion will act on the element immediately preceding it.
echo {part-1,part-2{a,b,c,d},part-3}
Skip advertYou can also nest expansions by creating a comma-delimited list of range expansions.
echo {{5..0},{1..5}}
Preamble and Postscript
You can place text before and after a brace expansion to have that text included in the results of the expansion.
- Text put in front of an expansion is called the preamble, while text placed behind a brace expansion is called the postscript.
This command uses a preamble.
echo chapter{1..3}
This example uses a postscript:
echo {contents,paper,bilbiography}.md
And this command uses both.
echo chapter-{1..4}.md
Expanding File Names and Directories
As you’ve probably guessed by now, one of the main uses of brace expansions is to create file and directory names that can be passed to other commands.
- We’ve been using echo as a convenient way to see exactly what happens when an expansion is triggered.
- You can substitute any command that takes filenames or directory names as input and use brace expansion with it.
To quickly create some files, use touch:
touch file-{1..4}.txt ls *.txt
If you have many files with the same base name but different file extensions and you want to perform an operation on a subset of them, brace expansions can help.
- Here, we’re compressing a subset of files that have “program” as the basename into a ZIP file called “source-code.zip.”
Development directories contain lots of files that will have the same basename as your main program.
- Usually, you don’t want to back up or distribute files like “.o” object files.
- This is a neat way to only include the file types of interest.
zip source-code program{.c,.h,.css}
This command will make a copy of a file and append “.bak” to it, making a backup copy of the original file.
- An interesting point to note is that the brace expansion contains a comma-separated list, but the first element is empty.
- If we hadn’t included the comma, the expansion wouldn’t have taken place.
cp brace/new/prog-1.c{,.bak} ls brace/new/prog-1.c.bak
To perform some action on two files in different directories, we can use a brace expansion in the path to the files.
In this example, the “brace” directory contains two subdirectories, one called “new” and one called “old.” They contain different versions of the same set of source code files.
- We’ll use the diff program to see the differences between the two versions of “prog-1.c.”
diff brace/{new,old}/prog-1.c
If you have a standard skeleton of directories that you need to create at the start of a project, you can create them quickly using brace expansion.
- The mkdir -p (parent) option creates any missing parent directories when a child directory is created.
mkdir -p {source,build,man,help{/pages,/yelp,/images}}
tree
You can use brace expansion with wget to download multiple files.
In this command, we’re going to download files from two directories, called “test1” and “test2.” Each directory holds two files called “picture1” and “picture2.”
wget https://www.URL-of-your-choice.com/test{1,2}/picture{001,002}.jpg
Listing the files shows you the files that were retrieved and how wget renames files to avoid name clashes with existing files.
ls picture*.*
Embrace the Brace
RELATED15 Special Characters You Need to Know for Bash
It seems that brace expansion is another one of Linux’s best-kept secrets.
- Many people tell me that they’ve never heard of brace expansion, while others inform me that it’s one of their favorite command-line tricks.
Give it a try and it just might find its way into your set of command-line go-to tricks.
Quelle
Brace expansion
Im einfachsten Fall verwendet man eine Präfix-Zeichenkette, gefolgt von beliebig vielen, mit geschweiften Klammern umschlossenen und durch Kommas getrennten Zeichen(ketten), wiederum gefolgt von einer optionalen Postfix-Zeichenkette.
Das Ergebnis sind nun Zeichenketten der Art "PräfixZeichenkette_1_Postfix", "PräfixZeichenkette_2_Postfix",..., "PräfixZeichenkette_n_Postfix".
$ echo Beispiel{_1_,_2_,_3_} Beispiel_1_ Beispiel_2_ Beispiel_3_
Präfix und Postfix können ihrerseits wiederum Klammererweiterungen sein und Klammererweiterungen können verschachtelt werden, sodass sich z. B.
- mit nur einem Befehl eine ganze Verzeichnishierarchie erzeugen lässt:
$ mkdir -p bsp/{ucb/{ex,edit},lib/{bla,foo}} $ du bsp | cut -b 3- bsp/ucb/ex bsp/ucb/edit bsp/ucb bsp/lib/bla bsp/lib/foo bsp/lib bsp
Der Klammer-Mechanismus der eine große Menge an Zeichenketten erzeugen kann.
- Muster für die Klammerexpansion (brace-expanded) haben eine optionale PREAMBLE, gefolgt von einer kommaseparierten Liste von Zeichenketten zwischen einem Paar von Klammern gefolgt von einem optionalem POSTSCRIPT.
- Die PREAMBLE wir jeder Zeichenkette vorangestellt, dass die Klammern enthalten, dass POSTSCRIPT wird an jede Ergebniszeichenkette abgehangen.
- Die Klammererweiterung kann auch verschachtelt werden.
- Das Ergebnis wird nicht sortiert, die links-zu-rechts-Ordnung bleibt erhalten.
$ echo sp{el,il,al}l spell spill spall
Die brace expansion wird vor allen anderen Expansionen ausgeführt und alle Zeichen, die für andere Expansionen eine besondere Bedeutung haben bleiben erhalten; es ist eine reine Textoperation.
- Die Bash führt keine syntaktische Interpretationen durch.
- Um Konflikte mit der parameter expansion zu vermeiden, werden Zeichenketten die mit "${" beginnen, nicht als brace expansion verstanden.
- Eine korrekt formulierte brace expansion muss eine unmaskierte öffnende und schließende Klammer besitzen und mindestens ein unmaskiertes Komma enthalten.
- Fehlerhaft formulierte brace expansion werden von der Bash nicht korrigiert.
Backup erstellen
$ cp -p /etc/apache2/plesk.conf.d/roundcube.conf{,.conf_back}
Brace expansion
Ähnlich wie die Expansion von Dateinamen ist die Expansion von geschweiften Klammern eine kompakte Methode, um mehrere ähnliche Argumente darzustellen.
Die folgenden vier Befehle sind gleichwertig:
$ ls file1.txt file2.txt file3.txt file4.txt file5.txt $ ls file{1,2,3,4,5}.txt $ ls file{1..5..1}.txt $ file{1..5}.txt
- Der erste Befehl listet jedes Argument explizit auf.
- Die anderen drei Befehle verwenden alle Klammererweiterungen, um die Argumente knapper auszudrücken:
- beim zweiten Befehl werden alle Möglichkeiten von 1 bis 5 angegeben, getrennt durch Kommas
- beim dritten Befehl wird eine numerische Folge angegeben ("von 1 bis 5, aufsteigend um 1")
- der vierte Befehl ist derselbe wie der dritte, lässt aber die ..1 implizit.
Wir können die Dateien auch in der umgekehrten Reihenfolge auflisten:
$ ls file5.txt file4.txt file3.txt file2.txt file1.txt $ ls file{5,4,3,2,1}.txt $ ls file{5..1..-1}.txt $ ls file{5..1}.txt
wobei die Standard-Inkrementgröße -1 ist, wenn der Endpunkt der Sequenz kleiner ist als der Startpunkt.
Da in der Bash das erste Wort eines Befehls das Programm ist, das ausgeführt wird, könnten wir den Befehl auch so schreiben:
$ {ls,file{1..5}.txt}
das ist der Lesbarkeit nicht förderlich!
Dasselbe kann mit der Expansion von Dateinamen gemacht werden.
Die Expansion von geschweiften Klammern kann wie die Expansion von Dateinamen durch jeden der Anführungszeichen-Mechanismen deaktiviert werden
'{', "{" oder \{
erzeugt eine tatsächliche geschweifte Klammer.
Beispiel
# root@debian ~ # chown -Rc dirkwagner.dirkwagner /media/daten/{tools,kurse,ebooks}