Try tail:
tail -n +2 "$FILE"
-n x
: Just print the last x
lines. tail -n 5
would give you the last 5 lines of the input. The +
sign kind of inverts the argument and make tail
print anything but the first x-1
lines. tail -n +1
would print the whole file, tail -n +2
everything but the first line, etc.
GNU tail
is much faster than sed
. tail
is also available on BSD and the -n +2
flag is consistent across both tools. Check the FreeBSD or OS X man pages for more.
The BSD version can be much slower than sed
, though. I wonder how they managed that; tail
should just read a file line by line while sed
does pretty complex operations involving interpreting a script, applying regular expressions and the like.
Note: You may be tempted to use
# THIS WILL GIVE YOU AN EMPTY FILE!
tail -n +2 "$FILE" > "$FILE"
but this will give you an empty file. The reason is that the redirection (>
) happens before tail
is invoked by the shell:
- Shell truncates file
$FILE
- Shell creates a new process for
tail
- Shell redirects stdout of the
tail
process to $FILE
tail
reads from the now empty $FILE
If you want to remove the first line inside the file, you should use:
tail -n +2 "$FILE" > "$FILE.tmp" && mv "$FILE.tmp" "$FILE"
The &&
will make sure that the file doesn't get overwritten when there is a problem.
Those settings (core.whitespace
and apply.whitespace
) are not there to remove trailing whitespace but to:
core.whitespace
: detect them, and raise errors
apply.whitespace
: and strip them, but only during patch, not "always automatically"
I believe the git hook pre-commit
would do a better job for that (includes removing trailing whitespace)
Note that at any given time you can choose to not run the pre-commit
hook:
- temporarily:
git commit --no-verify .
- permanently:
cd .git/hooks/ ; chmod -x pre-commit
Warning: by default, a pre-commit
script (like this one), has not a "remove trailing" feature", but a "warning" feature like:
if (/\s$/) {
bad_line("trailing whitespace", $_);
}
You could however build a better pre-commit
hook, especially when you consider that:
Committing in Git with only some changes added to the staging area still results in an “atomic” revision that may never have existed as a working copy and may not work.
For instance, oldman proposes in another answer a pre-commit
hook which detects and remove whitespace.
Since that hook get the file name of each file, I would recommend to be careful for certain type of files: you don't want to remove trailing whitespace in .md
(markdown) files!
Best Answer
You can use the in place option
-i
ofsed
for Linux and Unix:Be aware the expression will delete trailing
t
's on OSX (you can usegsed
to avoid this problem). It may delete them on BSD too.If you don't have gsed, here is the correct (but hard-to-read) sed syntax on OSX:
Three single-quoted strings ultimately become concatenated into a single argument/expression. There is no concatenation operator in bash, you just place strings one after the other with no space in between.
The
$'\t'
resolves as a literal tab-character in bash (using ANSI-C quoting), so the tab is correctly concatenated into the expression.