The command line is powerful but more than a little intimidating. Our community resource is intended to provide helpful one-liners and script code specifically drawn from real-life examples in archives and libraries. Take these, use them in your workflows, change them up, contribute back! Remember: you have to crawl before you walk. (See what we did there with the acronym?)
Each button displays helpful information about how to perform a wide variety of tasks on the command line. To use this site, click on the task you would like to perform. A new window will open up with a sample command and a description of how that command works. You can copy this command and understand how the command works with a breakdown of each of the flags.
Practice more command line wizardry with this Command Line Crash Course from Learn Code the Hard Way.
cp -a -i -v *.jpg destination
Copy all jpg files into another directory and preserve timestamps.
rename -n -v "s/\s+/_g" *
This command will test a batch replacement of all whitespace characters in a filename with underscores. You must have the rename
command installed to use it; if you encounter an error, it is possible you do not have rename
installed.
mkdir -p -v disk{001..100}/{rawFiles,normalizedFiles,reports}
This command makes one hundred sequentially named directories with a common prefix, and create three subdirectories (named rawFiles, normalizedFiles, and reports) underneath each parent directory.
rsync -a -h --progress --stats --exclude=".*" --exclude="~*" --log-file=log_file source destination
This command will recursively synchronize select files from one directory to another. (Note: rsync is generally used when you are copying data off of one storage medium to another, such as from your workstation to an external hard drive.)
for files in *; do mv ${files} ${files}.doc; done
Append the extension .doc to all files in a directory.
This script, which uses a loop, deploys the move command to rename a directory of files with their current filename plus the extension .doc. This will be helpful when working with a folder of homogenous files of the same type that, for one reason or another, lack file extensions. The absence of file extensions is a very common pattern of documents from the mid to late 1990s. This script quickly solves the problem and can be executed directly from your Terminal window.
for i in *.wav; do mv $i $(echo $i | sed 's/MAC/MN/g'); done
Rename WAV files in a directory by substituting the pattern MAC for MN.
find source -iname "*.xlsx" -exec rsync {} destination \;
Find and rsync all excel files in any subdirectory from source to a single directory at destination.
This command can be used to quickly aggregate multiple files to a single place for analysis. For example, copying metadata files from the data/ directory of a large number of bags.
If files do not have unique names, they will be overwritten at destination.
ls *.zip
This will find all of the .zip files in a particular directory. Note that it will not find files in subdirectories.
ls *.mp3 | wc -l
This command will count the number of MP3 files in a directory. Note that it will not count files in subdirectories.
wc
to only print the number of linescut -f2 input_file
This will print the second column of a tab-delimited file.
cut -f2 -d',' input_file
If your file uses a different delimited, such as a comma, you can adjust the command as shown above.
find -type f -printf '%T+\t%TY-%TB-%Td\t%p\n' | sort -n | head -n 1 | cut -f2,3
Find and print the oldest file and display its modified date in a friendly format.
echo "Digital Folders: $(find -type d | wc -l); Digital Files: $(find -type f | wc -l)"
The script queries a directory (using find), counts the number of new lines (using wc) to determine the number of directories (-type d) and files (-type f), then prints the output to the screen.
find -type d
to find all directories and then pipes that to wc -l
to count the number of lines of output.wc -l
to count the number of lines of output.Don't forget to end the command with quotes.
diff input_file_1 input_file_2
This will compare two textfiles and show the differences, if any.
cmp -l input_file_1 input_file_2
This will compare two binary streams and show the address and bytes of each difference, if any.
echo "100 * $(cmp -l input_file_1 input_file_2 | wc -l)/$(wc -c input_file_2 | cut -d' ' -f4)" | bc -l
This will compare two binary streams and show the address and bytes of each difference, if any.
For example, if two disk images of the same item have different checksums this will indicate how different they are.
Or, if you suspect that an operation has corrupted a bitstream, this will indicate the amount of corruption.
There's a lot going on here, but if you'd like to adapt the command, the gist of it is:
echo "100 * $(commands to find number of different bytes)/$(commands to find total number of bytes)" | bc -l
ls -alR /set/your/path/here > /set/your/output/path/inventory.txt
Extract a list of files/directories (as well as filesystem data about the files/directories) to a "space" separated text file that you can parse separately from the CLI interface.
du -sch /set/your/path/here/*
This will give you disk usage information for all files in a chosen directory.
-s -c -h
instead. Each letter represents a different, chosen option for the command.-s
indicates that you want one entry per file.-c
indicates that you want to calculate the grand total.-h
indicates that you want these results in human-readable units.
set -o noclobber
Set a flag so that you don't accidentally overwrite existing files when redirecting output from another command. This can be helpful if you are trying to create log files from the output of your script, but want to ensure that you don't write over any file that already exists.
Add this line after #!/bin/bash
and before the rest of your code starts.
You can also issue this command in a Terminal window, but know that its effects are not permanent. (Meaning that, if you open a new Terminal window, you'll have to issue the command again to get the same effect.)
set -o errexit
Set a flag so that if any one part of your shell script returns an error, the entire script stops. This can be super helpful if you have a loop in your script: the script will not issue multiple consecutive errors but instead quit after the first one. This also can be helpful if you are debugging someone else's code and are not sure why it is not working on your system.
Add this line after #!/bin/bash
and before the rest of your code starts.
You can also issue this command in a Terminal window, but know that its effects are not permanent. (Meaning that, if you open a new Terminal window, you'll have to issue the command again to get the same effect.)
OIFS=$IFS
IFS=$'\n'
[script text]
IFS=$OIFS
Set a flag so that bash only interprets new lines as delimiters. Use this if you find that, in your code, you are getting weird errors because certain filenames have spaces in them, and there's no other way around that. (i.e., If you're not allowed or don't want to rename files that have spaces in them.)
Add the first two lines after #!/bin/bash
and before the rest of your code starts.
At the end of the script, use the last line to re-set $IFS to its original value.
ctrl+a
Sometimes when you're editing a command, the part you want to edit is buried at the beginning of the line. In that case, it can be faster to jump to the start of the line and move the cursor to the part you want to edit, instead of moving backwards from the end of the line.
On the keyboard, press the control
key and the a
at the same time, and the cursor will move to the start of line.
Your console might have other shortcuts for moving the cursor forward or backward one word at a time.
On Mac or Linux, hold alt/option
and click with the mouse
Sometimes when you're editing a command, it can be frustrating to move the cursor to the right position with the arrow keys. In that case, it can be faster to jump to the spot you want to edit directly.
On the keyboard, press the alt/option
key and then click on the location where you want to place the cursor on the command line.
ctrl+c
When:
ctrl+c
on the keyboard.
If one press doesn't work, try holding ctrl
and tapping c
.
The terminal saves the commands that you enter into a history file. When you press up
, the terminal retrieves lines from this history file one-by-one. It can be helpful to save more than the default number of commands. To do that you need to increase the storage of the history cache and history file.
echo "export $HISTSIZE=5000" >> ~/.bash_profile
echo "export $HISTFILESIZE=5000" >> ~/.bash_profile
Remember that super-long, super-complicated, super-great bash command you used once? Want to use it again but don't want to search your commands one up
press at a time? This command searches your saved command history using grep.
history | grep "search_term"
.
is a wildcard character.Created by Jarrett Drake and Dianne Dietrich.
Help us add more helpful command line scripts for archivists and librarians: Contribute on GitHub!
This tool has been adapted from the amazing ffmprovisr. We simply could not done it without them. Check it out!