4  File Management

5 File Management

In this chapter, we will explore commands for file management including:

  • create new file/change timestamps
  • copying files
  • renaming/moving files
  • deleting files
  • comparing files
Command Description
touch Create empty file(s)/change timestamp
cp Copy files & folders
mv Rename/move file
rm Remove/delete file
diff Compare files

5.1 Create new file

touch modifies file timestamps which is information associated with file modification. It can be any of the following:

  • access time (the last time the file was read)
  • modification time (the last time the contents of the file was changed)
  • change time (the last time the file’s metadata was changed)

If the file does not exist, it will create an empty file of the same name. Let us use touch to create a new file myanalysis.R.

touch myanalysis.R
ls
analysis.R
bash.R
bash.Rmd
bash.sh
cran_log_sample.csv.gz
imports_blorr.txt
imports_olsrr.txt
lorem-ipsum.txt
main_project.zip
myanalysis.R
myfiles
mypackage
myproject
package_names.txt
pkg_names.txt
r
release_names.tar
release_names.tar.gz
release_names.txt
release_names_18.txt
release_names_19.txt
urls.txt
zip_example.zip

5.2 Copy Files/Folders

cp makes copies of files and directories. The general form of the command is cp source destination. By default, it will overwrite files without prompting for confirmation so be cautious while copying files or folders.

5.2.1 Copy files in same folder

Let us create a copy of release_names.txt file and name it as release_names_2.txt.

cp release_names.txt release_names_2.txt
ls
analysis.R
bash.R
bash.Rmd
bash.sh
cran_log_sample.csv.gz
imports_blorr.txt
imports_olsrr.txt
lorem-ipsum.txt
main_project.zip
myanalysis.R
myfiles
mypackage
myproject
package_names.txt
pkg_names.txt
r
release_names.tar
release_names.tar.gz
release_names.txt
release_names_18.txt
release_names_19.txt
release_names_2.txt
urls.txt
zip_example.zip

5.2.2 Copy files into different folder

To copy a file into a different directory/folder, we need to specify the name of the destination folder. If the copied file should have a different name, then we need to specify the new name of the file as well. Let us copy the release_names.txt file into the r_releases folder (we will retain the same name for the file as we are copying it into a different folder).

mkdir -p r_releases
cp release_names.txt r_releases/release_names.txt

Let us check if the file has been copied by listing the files in the r_releases folder using ls.

ls r_releases
release_names.txt

5.2.3 Copy folders

How about making copies of folders? Use the -r option to copy entire folders. Let us create a copy of the r folder and name it as r2. The -r option stands for --recursive i.e. copy directories recursively.

cp -r r r2
ls
analysis.R
bash.R
bash.Rmd
bash.sh
cran_log_sample.csv.gz
imports_blorr.txt
imports_olsrr.txt
lorem-ipsum.txt
main_project.zip
myanalysis.R
myfiles
mypackage
myproject
package_names.txt
pkg_names.txt
r
r2
r_releases
release_names.tar
release_names.tar.gz
release_names.txt
release_names_18.txt
release_names_19.txt
release_names_2.txt
urls.txt
zip_example.zip

5.3 Move/Rename Files

mv moves and renames files and directories. Using different options, we can ensure

  • files are not overwritten
  • user is prompted for confirmation before overwriting files
  • details of files being moved is displayed
Command Description
mv Move or rename files/directories
mv -f Do not prompt for confirmation before overwriting files
mv -i Prompt for confirmation before overwriting files
mv -n Do not overwrite existing files
mv -v Move files in verbose mode

Let us move the release_names_2.txt file to the r_releases folder.

mv release_names_2.txt r_releases

Use ls to verfiy if the file has been moved. As you can see, release_names_2.txt is not present in the current working directory.

ls
analysis.R
bash.R
bash.Rmd
bash.sh
cran_log_sample.csv.gz
imports_blorr.txt
imports_olsrr.txt
lorem-ipsum.txt
main_project.zip
myanalysis.R
myfiles
mypackage
myproject
package_names.txt
pkg_names.txt
r
r2
r_releases
release_names.tar
release_names.tar.gz
release_names.txt
release_names_18.txt
release_names_19.txt
urls.txt
zip_example.zip

Let us check if release_names_2.txt is present in the r_releases folder. Great! We have successfully moved the file into a different folder.

ls r_releases
release_names.txt
release_names_2.txt

5.3.1 Move files in verbose mode

To view the details of the files being moved/renamed, use the -v option. In the below example, we first stage release_names_3.txt and then move it into the r_releases folder using mv.

cp release_names.txt release_names_3.txt
mv -v release_names_3.txt r_releases
renamed 'release_names_3.txt' -> 'r_releases/release_names_3.txt'

5.3.2 Do not overwrite existing files

How do we ensure that files are not overwritten without prompting the user first? In the below example, we will try to overwrite the release_names_2.txt in the r_releases folder using mv and see what happens. But first, let us look at the contents of the release_names_2.txt file using the cat command.

We will look into the cat command in more detail in the next chapter but for the time being it is sufficient to know that it prints contents of a file. The file contains release names of different R versions.

cat r_releases/release_names_2.txt
Unsuffered Consequences
Great Pumpkin
December Snowflakes
Gift-Getting Season
Easter Beagle
Roasted Marshmallows
Trick or Treat
Security Blanket
Masked Marvel
Good Sport
Frisbee Sailing
Warm Puppy
Spring Dance
Sock it to Me
Pumpkin Helmet
Smooth Sidewalk
Full of Ingredients
World-Famous Astronaut
Fire Safety
Wooden Christmas Tree
Very Secure Dishes
Very, Very Secure Dishes
Supposedly Educational
Bug in Your Hair
Sincere Pumpkin Patch
Another Canoe
You Stupid Darkness
Single Candle
Short Summer
Kite Eating Tree

In our current working directory, we will create another file of the same name i.e. release_names_2.txt but its contents are different from the file in the r_releases folder. It contains the string release_names and nothing else. We will now move this file into the r_releases folder but use the option -n to ensure that the file in the r_releases folder is not overwritten. We can confirm this by printing the contents of the file in the r_releases folder.

The echo command is used to print text to the terminal or to write to a file. We will explore it in more detail in the next chapter.

echo "release_names" > release_names_2.txt 
mv -n release_names_2.txt r_releases
cat r_releases/release_names_2.txt
mv: not replacing 'r_releases/release_names_2.txt'
Unsuffered Consequences
Great Pumpkin
December Snowflakes
Gift-Getting Season
Easter Beagle
Roasted Marshmallows
Trick or Treat
Security Blanket
Masked Marvel
Good Sport
Frisbee Sailing
Warm Puppy
Spring Dance
Sock it to Me
Pumpkin Helmet
Smooth Sidewalk
Full of Ingredients
World-Famous Astronaut
Fire Safety
Wooden Christmas Tree
Very Secure Dishes
Very, Very Secure Dishes
Supposedly Educational
Bug in Your Hair
Sincere Pumpkin Patch
Another Canoe
You Stupid Darkness
Single Candle
Short Summer
Kite Eating Tree

As you can observe, the contents of the file in the r_releases folder has not changed. In the next section, we will learn to overwrite the contents using the -f option.

5.3.3 Do not prompt for confirmation before overwriting files

What if we actually intend to overwrite a file and do not want to be prompted for confirming the same. In this case, we can use the -f option which stands for --force i.e. do not prompt before overwriting. Let us first print the contents of the release_names_2.txt file in the r_releases folder.

cat r_releases/release_names_2.txt
Unsuffered Consequences
Great Pumpkin
December Snowflakes
Gift-Getting Season
Easter Beagle
Roasted Marshmallows
Trick or Treat
Security Blanket
Masked Marvel
Good Sport
Frisbee Sailing
Warm Puppy
Spring Dance
Sock it to Me
Pumpkin Helmet
Smooth Sidewalk
Full of Ingredients
World-Famous Astronaut
Fire Safety
Wooden Christmas Tree
Very Secure Dishes
Very, Very Secure Dishes
Supposedly Educational
Bug in Your Hair
Sincere Pumpkin Patch
Another Canoe
You Stupid Darkness
Single Candle
Short Summer
Kite Eating Tree

Now we will create another file of the same name in the current working directory but with different content and use the -f option to overwrite the file in the r_releases folder. You can see that the contents of the file in the r_releases folder has changed.

echo "release_names" > release_names_2.txt 
mv -f release_names_2.txt r_releases
cat r_releases/release_names_2.txt
release_names

5.4 Remove/Delete Files

The rm command is used to delete/remove files & folders. Using additional options, we can

  • remove directories & sub-directories
  • forcibly remove directories
  • interactively remove multiple files
  • display information about files removed/deleted
Command Description
rm Remove files/directories
rm -r Recursively remove a directory & all its subdirectories
rm -rf Forcibly remove directory without prompting for confirmation or showing error messages
rm -i Interactively remove multiple files, with a prompt before every removal
rm -v Remove files in verbose mode, printing a message for each removed file

5.4.1 Remove files

Let us use rm to remove the file myanalysis.R (we created it earlier using the touch command).

rm myanalysis.R
ls
analysis.R
bash.R
bash.Rmd
bash.sh
cran_log_sample.csv.gz
imports_blorr.txt
imports_olsrr.txt
lorem-ipsum.txt
main_project.zip
myfiles
mypackage
myproject
package_names.txt
pkg_names.txt
r
r2
r_releases
release_names.tar
release_names.tar.gz
release_names.txt
release_names_18.txt
release_names_19.txt
urls.txt
zip_example.zip

5.4.2 Recursive Deletion

How about folders or directories? We can remove a directory and all its contents including sub-directories using the option -r which stands for --recursive and removes directories and their contents recursively. Let us first stage a disposable copy as myproject1, then remove it and all its contents.

cp -r myproject myproject1
rm -r myproject1
ls
analysis.R
bash.R
bash.Rmd
bash.sh
cran_log_sample.csv.gz
imports_blorr.txt
imports_olsrr.txt
lorem-ipsum.txt
main_project.zip
myfiles
mypackage
myproject
package_names.txt
pkg_names.txt
r
r2
r_releases
release_names.tar
release_names.tar.gz
release_names.txt
release_names_18.txt
release_names_19.txt
urls.txt
zip_example.zip

5.4.3 Force Removal

Use the -f option which stands for --force to forciby remove directory and all its contents without prompting for confirmation or showing error messages. Let us first stage a disposable copy as myproject2, then remove it and all its contents.

cp -r myproject myproject2
rm -rf myproject2
ls
analysis.R
bash.R
bash.Rmd
bash.sh
cran_log_sample.csv.gz
imports_blorr.txt
imports_olsrr.txt
lorem-ipsum.txt
main_project.zip
myfiles
mypackage
myproject
package_names.txt
pkg_names.txt
r
r2
r_releases
release_names.tar
release_names.tar.gz
release_names.txt
release_names_18.txt
release_names_19.txt
urls.txt
zip_example.zip

5.4.4 Verbose Mode

Remove files in verbose mode, printing a message for each removed file. This is useful when you want to see the details of the files being removed. In the below example, we will remove all files with .txt extension from the myfiles folder. Instead of specifying the name of each text file, we use the wildcard * along with .txt i.e. any file with the extension .txt will be removed.

cd myfiles
rm -v *.txt
removed 'release_names.txt'
removed 'release_names_18.txt'
removed 'release_names_19.txt'

5.5 Compare Files

diff stands for difference. It is used to compare files line by line and display differences. It also indicates which lines in one file must be changed to make the files identical. Using additional options, we can

  • ignore white spaces while comparing files
  • show differences sidy by side
  • show differences in unified format
  • compare directories recursively
  • display names of files that differ
Command Description
diff Compare files & directories
diff -w Compare files; ignoring white spaces
diff -y Compare files; showing differences side by side
diff -u Compare files; show differences in unified format
diff -r Compare directories recursively
diff -rq Compare directories; show the names of files that differ

5.5.1 Compare Files

Let us compare the contents of the following files

  • imports_olsrr.txt
  • imports_blorr.txt

The files contain the names of R packages imported by the olsrr and blorr packages respectively (Full disclosure: both the above R pakages are developed by Rsquared Academy.).

diff uses certain special symbols and gives instructions to make the files identical. The instructions are on how to change the first file to make it identical to the second file. We list the symbols below

  • a for add
  • c for change
  • d for delete

We will use the -w option to ignore white spaces while comparing the files.

diff -w imports_olsrr.txt imports_blorr.txt || true
4a5
> caret

Let us interpret the results. 4a5 indicates after line 4 in file 1, add line 5 from file 2 to make both the files identical i.e. add caret which is line 5 in imports_blorr.txt after line 4 in imports_olsrr.txt which will make both the files identical.

Let us change the file order and see the instructions from diff.

diff -w imports_blorr.txt imports_olsrr.txt || true
5d4
< caret

5d4 indicates delete line 5 from file 1 to match both the files at line4 i.e. delete caret which is line 5 in imports_blorr.txt to make both the files identical.

5.5.2 Side By Side

To view the differences between the files side by side, use the -y option.

diff -y imports_olsrr.txt imports_blorr.txt || true
car 
                                  | car
checkmate
                                  | checkmate
cli
                                  | cli
clisymbols
                                  | clisymbols
                                  > caret

5.5.3 Unified Format

To view the differences between the files in a unified format, use the -u option.

diff -u imports_olsrr.txt imports_blorr.txt || true
--- imports_olsrr.txt   2021-06-02 11:44:47.000000000 +0000
+++ imports_blorr.txt   2021-06-02 11:44:47.000000000 +0000
@@ -1,4 +1,5 @@
-car 
-checkmate
-cli
-clisymbols
+car
+checkmate
+cli
+clisymbols
+caret

5.5.4 Compare Recursively

To compare recursively, use the -r option. Let us compare the mypackage and myproject folders.

diff -r mypackage myproject || true
Only in mypackage: .Rbuildignore
Only in mypackage: DESCRIPTION
Only in mypackage: LICENSE
Only in mypackage: NAMESPACE
Only in mypackage: NEWS.md
Only in mypackage: R
Only in myproject/data: processed
Only in myproject/data: raw
Only in mypackage: docs
Only in mypackage: man
Only in myproject: output
Only in myproject: run_analysis.R
Only in mypackage: tests
Only in mypackage: vignettes

5.5.5 File Details

To compare directories and view the names of files that differ, use the -rq option. In the below example, we look at the names of files that differ in mypackage and myproject folders.

diff -rq mypackage myproject || true
Only in mypackage: .Rbuildignore
Only in mypackage: DESCRIPTION
Only in mypackage: LICENSE
Only in mypackage: NAMESPACE
Only in mypackage: NEWS.md
Only in mypackage: R
Only in myproject/data: processed
Only in myproject/data: raw
Only in mypackage: docs
Only in mypackage: man
Only in myproject: output
Only in myproject: run_analysis.R
Only in mypackage: tests
Only in mypackage: vignettes

5.6 R Functions

In R, file operations can be performed using functions from both base R and the fs package.

Command R
touch file.create() / fs::file_create() / fs::file_touch()
cp file.copy() / fs::file_copy() / fs::dir_copy()
mv file.rename() / fs::file_move()
rm file.remove() / fs::file_delete()
diff

5.7 Exercises

  1. In cline/, run touch myexercise.R then ls and confirm the new empty file appears. Then run cp release_names.txt release_names_ex.txt and ls — you should see both files. Clean up with rm myexercise.R release_names_ex.txt.
  2. In cline/, run mkdir -p ex_releases, then cp release_names.txt ex_releases/ and check with ls ex_releases — you should see 1 file. Then run touch myexercise2.R followed by mv -v myexercise2.R ex_releases/ and observe the verbose message. Verify with ls ex_releases (2 files), then clean up with rm -rf ex_releases.
  3. In cline/, run diff imports_olsrr.txt imports_blorr.txt || true. Note the short difference block with a/d/c instructions and which package name is the extra line. Then re-run with diff -y (side-by-side) and diff -u (unified) — describe in one sentence each how the views differ.