Use the touch command:
The touch utility sets the modification and access times of files to the
current time of day. If the file doesn't exist, it is created with
default permissions.
A FILE argument that does not exist is created as an empty file by the
touch command, unless the -c option is supplied.
Example:
touch newfile
Answer from Isaiah on askubuntu.comUse the touch command:
The touch utility sets the modification and access times of files to the
current time of day. If the file doesn't exist, it is created with
default permissions.
A FILE argument that does not exist is created as an empty file by the
touch command, unless the -c option is supplied.
Example:
touch newfile
> newfile
Will also create an empty file. If the file does already exist, it will be truncated (emptied). To keep the file contents, use >> for appending as in:
>> file
Even if the file exists, the contents will be untouched.
Edit: If you don't have any content to type, this one is faster:
user@host$ :> newfile
user@host$ :>> new_or_existing_file
Note. : is the command here. It is not part of the prompt.
If you want to create as root
: | sudo tee thefile
To not truncate existing file:
: | sudo tee -a thefile
How do I create a new empty file in a bash script? - Unix & Linux Stack Exchange
How to create a new file in unix? - Stack Overflow
linux - Create empty multiple files in Unix that contain 0 bytes using awk or bash? - Stack Overflow
linux - shell script to create empty files with all possible permissions - Stack Overflow
Videos
Try > workdirectory/filename.txt
This would:
- truncate the file if it exists
- create if it doesn't exist
You can consider it equivalent to:
rm -f workdirectory/filename.txt; touch workdirectory/filename.txt
The command is lowercase: touch filename.
Keep in mind that touch will only create a new file if it does not exist! Here's some docs for good measure: http://unixhelp.ed.ac.uk/CGI/man-cgi?touch
If you always want an empty file, one way to do so would be to use:
echo "" > filename
How about:
touch $(seq 2)
or:
touch
/.txt/')
if you want a suffix?
If you really want to do it in awk:
seq 2 | awk '{system(">" "empty" FNR ".txt")}'
That's not very clever though because it creates a whole new process for every line that awk reads.
@EdMorton's suggestion is therefore preferable, as he uses awk's internal printf rather than creating a separate process:
seq 2 | awk '{printf "" > "empty" NR ".txt"}'
You would be better to use this:
touch {1..2}.txt
which only creates one process. However, that will not reduce to zero the size of any pre-existing files you may have - I don't generally like to assume folk are happy to lose data unless they explicitly say so in their question.
Do a loop:
for ((i=0; i < 512; i++)); do
mod=$(printf "%03o" "$i");
touch ${mod}.txt; chmod $mod $mod.txt;
done
Rather than trying to construct the names, if you want the names to look like the output of ls -l, just do something like
for ((i=0; i < 512; i++)); do
mod=$(printf "%03o" "$i")
touch ${mod}.txt
chmod $mod $mod.txt
n=$(ls -l $mod.txt | cut -b1-10)
mv -- $mod.txt "$n.txt"
done
It's just a permutations problem.
p=( --- --x -w- -wx r-- r-x rw- rwx ) # the set of permissions
for u in "${p[@]}"; do for g in "${p[@]}"; do for o in "${p[@]}"; do
f="task5/$u$g$o.txt"; touch -- "$f" && chmod "u=${u//-/},g=${g//-/},o=${o//-/}" -- "$f";
done; done; done
NOTE
- thanks to @kvantour for pointing out I was passing dashed to chmod, and that it doesn't know what to do with them. I am surprised I wasn't getting errors.
Let's break it down and look at what's happening.
If you have any questions about what permissions sets mean or how chmod works, see here.
So for each of the user, group, or other, there are eight possible symbolic representations (representing the values of one octal digit, 0-7).
We set those into a simple array we can loop over.
p=( --- --x -w- -wx r-- r-x rw- rwx ) # the set of permissions
You can access any element with it's octal digit (technically the decimal equivalent, but that doesn't matter unless you go over 7) so ${p[5]} is r-x. Indexing with @ returns the whole array, so the loops walk through them sequentially with ${p[@]}.
To get every possible permutation, we loop over them for each of user/group/other.
for u in "${p[@]}"; do # assign each permission set for the user
for g in "${p[@]}"; do # assign each permission set for the group
for o in "${p[@]}"; do # assign each permission set for the other
This is just simple iterations in nested loops to hit every permutation.
f="task5/$u$g$o.txt" # assign the permissions string AS the filename
By putting the path and filename info into a variable, we can maintain any changes in one place, and it makes the rest of the line shorter and easier to read.
touch -- "$f" && # create the file and test for success
touch will create an empty file. Because the filenames could sometimes begin with a dash (any time the permissions disallow user read), we give touch a first argument of --, which is a *NIX standard idiom meaning "options are done now, anything left is arguments"; otherwise it would try to interpret a leading dash as an invalid option set and fail. This won't be a problem while you are putting "task5/" at the beginning of the filename, but if you end up using the filename bare it would.
The && is a boolean test to see whether touch succeeded. If it did not, then we silently skip trying the chmod (touch should have emitted an error message for your debugging, but if that fails, you probably got a ton of them, and will need to fix whatever ...)
chmod "u=${u//-/},g=${g//-/},o=${o//-/}" -- "$f" # change the permissions
This uses chmod's symbolic mode. We have the permissions of each section from the nexted loops - just apply them. Again, we use the -- to tell chmod when we are done passing options so that leading dashes in filenames won't be a problem later if you refactor just just cd into the directory and create the files locally, though even then you could always prefix ./ or $PWD/ on it.
We have to get rid of thew dashes in the symbolic file modes, though, as (thanks agains @kvantour) chmod doesn't recognize those. An inline string edit works beautirully: in "u=${u//-/},g=${g//-/},o=${o//-/}", the // inside the variable spec is a replacement of all occurrences, replacing - with the nothing between the following / and }.
done; done; done # these just close each of the loops
We could (and probably should) put each of these on separate lines, but the interpreter doesn't care since we used semicolons. It lets us compact the code to put the loop nesting and closures on lines together, so long as you are comfortable with the ONE thing that's changing being obvious enough.
Anything you still have questions about that I didn't cover?
Alternate
Another version, because I like going through a loop once instead of nested shenannigans...
p=( --- --x -w- -wx r-- r-x rw- rwx ) # the set of permissions
for dec in {0..511}; do oct="$(printf "%03o" "$dec")"
u="${p[${oct:0:1}]}"; g="${p[${oct:1:1}]}"; o="${p[${oct:2:1}]}";
f="task5/$u$g$o.txt"; touch "$f"; chmod "u=${u//-/},g=${g//-/},o=${o//-/}" "$f";
done
This walks through the combinations numerically, converts decimal to octal with printf, slices each digit out of the octal permission set with basic substring parsing and uses it to look up the relevant string from the array, assign the segments, assign the resulting filename, touch/create the file, then apply the scrubbed permissions strings with chmod. It's once-through and faster, if a little harder to understand.
u="${p[${oct:0:1}]}" # grabs 1 byte from offset 0 of $oct as index to $p
As suggested, to skip the decimal to octal conversion step, replace:
for dec in {0..511}; do oct="$(printf "%03o" "$dec")"
with
for oct in {0..7}{0..7}{0..7}; do