3

I have multiple files(100-1000) in foo dir. I want to append each filename to its own content. I think the for loop should resolve appending a random string to for each file,

for f in *; do printf "%10s \n" $(shuf -i 50-100 -n 50 -r) >> $f; done

How can I append filename to all this shuffled numbers, directly concatanate them?

for f in *; do printf "%10s \n" $f $(shuf -i 50-100 -n 50 -r) >> $f; done

result in file 5:

5
67
89
69
...

expected result:

567
589
569
...
  • 2
    You want to append each filename, but you talk about appending random strings, too? What are you trying to do exactly? Can you show what the sample input and output would be for a single file? If the files don't affect each other, then just forget about the loop for now, it only distracts from the main point. If the files do affect each other, then how? – ilkkachu Jul 9 at 11:11
  • You are right, the main point is how can I repeat a variable with count of the shuf -n argument. I am trying to write a code that applies hundreds of files so for loop inescapable I think. – Murat Salik Jul 9 at 11:22
  • You already got it - simply store the result from shuf in a variable and use that twice. – Panki Jul 9 at 11:29
5

Ok, if I get it right, you want to prefix a fixed string to all numbers printed by shuf. If so, just add that string to the start of the printf format string:

$ printf "x%10s\n" $(shuf -i 50-100 -n 3 -r)
x        71
x        70
x        92

Change the %10s to %s get them back to back without the whitespace. Similarly, you can use the loop variable instead:

$ for f in 1 2 3; do printf "$f%s\n" $(shuf -i 50-100 -n 2 -r); done
151
197
268
256
364
354

Add the >> "$f" to redirect to files.

Note that since the fixed part is part of the format string here, any % signs and backslashes would be interpreted by printf.

| improve this answer | |
  • printf "%s%s\n" "$f" "$(shuf ...)" would be better: if the filename happens to contain a %, you'll be protected this way. – glenn jackman Jul 9 at 11:48
  • 2
    @glennjackman, indeed, except that it doesn't work. :) You can't quote the output of shuf as this relies on wordsplitting it. Even then, you'd get the fixed part only once, try something like printf "%s %s\n" xx $(shuf -i 50-100 -n 4 -r). – ilkkachu Jul 9 at 11:50
  • We could use something like for f in *; do for n in $(shuf ...); do printf "%s%s\n" "$f" "$n"; done; done – ilkkachu Jul 9 at 11:53
6

Store result of shuf into a bash array, then use substitution in the parameter expansion to prepend $f:

mapfile -t shuf < <(shuf -i 50-100 -n 50)
printf '%10s \n' "${shuf[@]/#/"$f"}" >>"$f"

With zsh, use ^ parameter expansion:

printf '%10s \n' "$f${(f)^"$(shuf -i 50-100 -n 50)"}" >> "$f"
| 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.