How to Remove the Last Character of a File in Unix

How can I remove the last character of a file in unix?

A simpler approach (outputs to stdout, doesn't update the input file):

sed '$ s/.$//' somefile
  • $ is a Sed address that matches the last input line only, thus causing the following function call (s/.$//) to be executed on the last line only.

  • s/.$// replaces the last character on the (in this case last) line with an empty string; i.e., effectively removes the last char. (before the newline) on the line.

    . matches any character on the line, and following it with $ anchors the match to the end of the line; note how the use of $ in this regular expression is conceptually related, but technically distinct from the previous use of $ as a Sed address.

  • Example with stdin input (assumes Bash, Ksh, or Zsh):

      $ sed '$ s/.$//' <<< $'line one\nline two'
    line one
    line tw

To update the input file too (do not use if the input file is a symlink):

sed -i '$ s/.$//' somefile

Note:

  • On macOS, you'd have to use -i '' instead of just -i; for an overview of the pitfalls associated with -i, see the bottom half of this answer.
  • If you need to process very large input files and/or performance / disk usage are a concern and you're using GNU utilities (Linux), see ImHere's helpful answer.

Remove last character from a file in unix

quick and dirty

sed 's/.$//' YourFile

a bit secure

sed 's/[|]$//' YourFile

allowing space

sed 's/[|][[:space:]]*$//' YourFile

same for only last char of last line (thansk @amelie for this comment) :
add a $in front so on quick and dirty it gives sed '$ s/.$//' YourFile

Removing first and last character of a big file via terminal

There is no fast way to do it in a shell.

head -c -1 < in.txt | tail -c +1 > out.txt

If you don't mind dropping to C, calling sendfile(2) with a *offset of 1 and a count of the size less 2 will likely be the fastest possible way.

Delete the last character in a specific column in unix

Awk solution:

awk 'BEGIN{ FS=OFS="|" }{ sub(/.$/, "", $20) }1' file
  • .$ - where . is any character at the end of the string $

The output:

U|0|1|10.95|10.95|0|0|0|0| |0| |0| |N|N| |N| |10335790|1| | |Y|N/A|
V|0|1|12.65|12.65|0|0|0|0| |0| |0| |N|N| |N| |10335790|1| | |Y|N/A|
P|0|1|15.57|15.57|0|0|0|0| |0| |0| |N|N| |N| |10335790|1| | |Y|N/A|

To perform a more specific replacement to may apply the substitution: sub(/[_#!]$/, "", $20)

shell script to remove last character of a line

Solution with sed

echo "1,abmc,fdsaf.,sdfsd," | sed 's/.$//g'

output:

1,abmc,fdsaf.,sdfsd

Explanation:

  • s/.$//g --> replaces .(any character) at the end of line with nothing (empty string).

How to remove last n characters from a string in Bash?

First, it's usually better to be explicit about your intent. So if you know the string ends in .rtf, and you want to remove that .rtf, you can just use var2=${var%.rtf}. One potentially-useful aspect of this approach is that if the string doesn't end in .rtf, it is not changed at all; var2 will contain an unmodified copy of var.

If you want to remove a filename suffix but don't know or care exactly what it is, you can use var2=${var%.*} to remove everything starting with the last .. Or, if you only want to keep everything up to but not including the first ., you can use var2=${var%%.*}. Those options have the same result if there's only one ., but if there might be more than one, you get to pick which end of the string to work from. On the other hand, if there's no . in the string at all, var2 will again be an unchanged copy of var.

If you really want to always remove a specific number of characters, here are some options.

You tagged this bash specifically, so we'll start with bash builtins. The one which has worked the longest is the same suffix-removal syntax I used above: to remove four characters, use var2=${var%????}. Or to remove four characters only if the first one is a dot, use var2=${var%.???}, which is like var2=${var%.*} but only removes the suffix if the part after the dot is exactly three characters. As you can see, to count characters this way, you need one question mark per unknown character removed, so this approach gets unwieldy for larger substring lengths.

An option in newer shell versions is substring extraction: var2=${var:0:${#var}-4}. Here you can put any number in place of the 4 to remove a different number of characters. The ${#var} is replaced by the length of the string, so this is actually asking to extract and keep (length - 4) characters starting with the first one (at index 0). With this approach, you lose the option to make the change only if the string matches a pattern; no matter what the actual value of the string is, the copy will include all but its last four characters.

You can leave the start index out; it defaults to 0, so you can shorten that to just var2=${var::${#var}-4}. In fact, newer versions of bash (specifically 4+, which means the one that ships with MacOS won't work) recognize negative lengths as the index of the character to stop at, counting back from the end of the string. So in those versions you can get rid of the string-length expression, too: var2=${var::-4}.

If you're not actually using bash but some other POSIX-type shell, the pattern-based suffix removal with % will still work – even in plain old dash, where the index-based substring extraction won't. Ksh and zsh do both support substring extraction, but require the explicit 0 start index; zsh also supports the negative end index, while ksh requires the length expression. Note that zsh, which indexes arrays starting at 1, nonetheless indexes strings starting at 0 if you use this bash-compatible syntax. But zsh also allows you to treat scalar parameters as if they were arrays of characters, in which case the substring syntax uses a 1-based count and places the start and (inclusive) end positions in brackets separated by commas: var2=$var[1,-5].

Instead of using built-in shell parameter expansion, you can of course run some utility program to modify the string and capture its output with command substitution. There are several commands that will work; one is var2=$(sed 's/.\{4\}$//' <<<"$var").

How to remove a character at the end of each line in UNIX

You can use sed:

sed 's/,$//' file > file.nocomma

and to remove whatever last character:

sed 's/.$//' file > file.nolast

SED : Remove last four characters from filename

if your file names don't have spaces, you can: (under your test_images dir)

ls -1|sed -r 's/(.*)....(\.jpg)$/mv & \1\2/'

to check the generated mv command. If it is ok, add |sh to the above command to do the actual renaming.

If your filenames have spaces, you need add quotes:

..../mv "&" "\1\2"/'|sh

This is a quick and dirty solution, since working with ls result is not good practice.

update: add "how to" example:

LsyHP 11:41:40 /tmp/test/img
kent$ ll
total 0
drwxr-xr-x 2 kent kent 120 Jan 4 11:41 ./
drwxr-xr-x 3 kent kent 160 Jan 4 11:41 ../
-rw-r--r-- 1 kent kent 0 Jan 4 11:41 006103insettedryshampoo-blossom7096.jpg
-rw-r--r-- 1 kent kent 0 Jan 4 11:41 008299bathmassagesponges-3packa1a4.jpg
-rw-r--r-- 1 kent kent 0 Jan 4 11:41 008507colgatetripleactiontoothpaste125d.jpg
-rw-r--r-- 1 kent kent 0 Jan 4 11:41 8729teatreeoilantisepticcream25g1005.jpg
LsyHP 11:41:43 /tmp/test/img
kent$ ls -1|sed -r 's/(.*)....(\.jpg)$/mv & \1\2/'
mv 006103insettedryshampoo-blossom7096.jpg 006103insettedryshampoo-blossom.jpg
mv 008299bathmassagesponges-3packa1a4.jpg 008299bathmassagesponges-3pack.jpg
mv 008507colgatetripleactiontoothpaste125d.jpg 008507colgatetripleactiontoothpaste.jpg
mv 8729teatreeoilantisepticcream25g1005.jpg 8729teatreeoilantisepticcream25g.jpg
LsyHP 11:41:52 /tmp/test/img
kent$ ls -1|sed -r 's/(.*)....(\.jpg)$/mv & \1\2/'|sh
LsyHP 11:41:57 /tmp/test/img
kent$ ll
total 0
drwxr-xr-x 2 kent kent 120 Jan 4 11:41 ./
drwxr-xr-x 3 kent kent 160 Jan 4 11:41 ../
-rw-r--r-- 1 kent kent 0 Jan 4 11:41 006103insettedryshampoo-blossom.jpg
-rw-r--r-- 1 kent kent 0 Jan 4 11:41 008299bathmassagesponges-3pack.jpg
-rw-r--r-- 1 kent kent 0 Jan 4 11:41 008507colgatetripleactiontoothpaste.jpg
-rw-r--r-- 1 kent kent 0 Jan 4 11:41 8729teatreeoilantisepticcream25g.jpg


Related Topics



Leave a reply



Submit