3

I'm working with standard input (cating two files together) and want all but the last 10 characters of the result to be passed through the next command.

All I can find through searching is using sed, awk or tr to remove the last n characters from each line, or head, tail or rev to remove n lines.

What could I use to do this from standard output piped into a command (hopefully simply and with a single command)?

Example:

Input:
SELECT 'A', 1, GETDATE() UNION ALL
SELECT 'B', 2, GETDATE() UNION ALL
...
SELECT 'Z', 2, GETDATE() UNION ALL

Output:
SELECT 'A', 1, GETDATE() UNION ALL
SELECT 'B', 2, GETDATE() UNION ALL
...
SELECT 'Z', 2, GETDATE()

For what it's worth, I'm using CygWin on Windows, so it needs to be with rather standard and old unix tools :(

  • Look at the last line, with 'Z'. The last 10 characters have been removed (the final UNION ALL), which makes it valid SQL syntax. – Ehryk Apr 20 '14 at 9:32
6

You could use head:

command | head -c-10

would remove the last 10 bytes from command output.

Quoting from man head:

   -c, --bytes=[-]K
          print the first K bytes of each  file;  with  the  leading  `-',
          print all but the last K bytes of each file

Since you specifically mention that the 10 characters to be removed would occur on one line, you could use sed too. Pipe the command output to:

sed '$s/\(.\{10\}\)$//'

or if your sed supports extended regex:

sed -r '$s/.{10}$//'

The syntax would be similar using perl:

perl -pe 's/.{10}$// if eof'
  • Does not appear to be supported in CygWin, head --version = 2.0 (1999). Any other alternatives? – Ehryk Apr 20 '14 at 9:36
  • @Ehryk The sed alternative might work for you. – devnull Apr 20 '14 at 9:49
  • The sed one works. How do you match on {end of stream} and not {end of line}? – Ehryk Apr 20 '14 at 9:50
  • @Ehryk The $ (before the s) is an address that specifies the last line. – devnull Apr 20 '14 at 9:51
  • How does this work with multibyte characters, like UTF-8? – evilsoup Apr 20 '14 at 11:13
3

You should use perl:

$ perl -lpe '$_=substr($_,0,-10) if eof' file
SELECT 'A', 1, GETDATE() UNION ALL
SELECT 'B', 2, GETDATE() UNION ALL
...
SELECT 'Z', 2, GETDATE()
  • Cool, that works, too! (Now I just have to figure out how to pipe it into sqlcmd and get it to execute it). – Ehryk Apr 20 '14 at 10:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.