4

This has probably been asked before, but I'm unsure how to word it. I want to type out a series of strings, which are basically string1, string2, string3; but without the redundant typing. So is there a way to type:

cat 'expr "/dev/input/event" "[1 2 3 4]" " "'*4

and have it resolve to:

cat /dev/input/event1 /dev/input/event2 /dev/input/event3 /dev/input/event4

so I don't have to type each device individually?

I also apologize for what's obviously a horrible misunderstanding of how the expr command works.

  • 5
    As an aside, this was tagged [regular-expression]. It's worth noting that filename wildcard patterns (globs) are not regular expressions. Even though they share some similarities, the syntax is different. Brace expansion is even more different. – ilkkachu Dec 31 '17 at 17:49
13

For expanding filenames (or device nodes) that exist already, then filename globbing is usually what you want:

The first would expand to event1 to event4, the second to any and all eventXX that exist:

cat /dev/input/event[1-4]
cat /dev/input/event*

If you don't care about existing files but want just strings, then brace expansion. Two ways to generate all of event1 to event4, the first one just takes a list, the second a range:

cat /dev/input/event{1,2,3,4}
cat /dev/input/event{1..4}

(The links are to BashGuide, which is a useful resource in itself.)

| improve this answer | |
6

What you're looking for is Brace Expansion:

3.5.1 Brace Expansion

You could do:

cat /dev/input/event{1..4}

I've created the following files on my machine:

$ touch input{1..4}
$ ls -l input{1..4}
-rw-r--r--  1 jessebutryn  staff  0 Dec 31 10:31 input1
-rw-r--r--  1 jessebutryn  staff  0 Dec 31 10:31 input2
-rw-r--r--  1 jessebutryn  staff  0 Dec 31 10:31 input3
-rw-r--r--  1 jessebutryn  staff  0 Dec 31 10:31 input4
$ for n in {1..4}; do echo "string$n">"input$n"; done
$ cat ./input{1..4}
string1
string2
string3
string4
$ echo {1..4}
1 2 3 4
$ echo {01..10}
01 02 03 04 05 06 07 08 09 10
$ echo {0..010}
000 001 002 003 004 005 006 007 008 009 010
$ echo {a..D}
a ` _ ^ ]  [ Z Y X W V U T S R Q P O N M L K J I H G F E D
$ 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
| improve this answer | |
3

The in this case more appropriate approaches have already been presented. For the sake of completeness (which may be necessary if the same value is needed several times):

declare -a args
for value in 1 2 3 4; do
    arg[$((index++))]="/dev/input/event${value}"
done

cat "${arg[@]}"
| improve this answer | |
0

If your shell doesn't support brace expansion you can resort to printf and xargs:

printf '/dev/input/event%s\n' 1 5 7 | xargs cat

If you want a sequence of numbers you can use seq and some string mangling instead of printf:

seq 10 20 | sed 's|^|/dev/input/event|' | xargs cat
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.