So I am on an old (fully aluminum) macbook pro running snow leopard and using terminal to ssh into remote hosts on my work network. I am noticing a strange thing when I copy and paste things in the terminal.
For example I will grep for something like this in a file:
samtools view sorted-616.bam | grep 'SOLEXA9:1:1:30:3316:10211' | head -n 1
and it gives
SOLEXA9:1:1:30:3316:10211 69 k26_179705 159 0 * = 159 0 TATGCCGCCAAACGCTTCCGCAAAGCTCTGTGTTTGACTATGTAGCGACTA CBCCCCCC#CCCCCCCCC?#CC?CC########################## RG:Z:1
But now when I select it, hit command+c to copy, and then command+v to paste, it comes out like this:
SOLEXA9:1:1:30:3316:1021169k26_1797051590*=1590TATGCCGCCAAACGCTTCCGCAAAGCTCTGTGTTTGACTATGTAGCGACTACBCCCCCC#CCCCCCCCC?#CC?CC##########################RG:Z:1
Notice how there are no spaces in between fields now. Is there a special method to copy and paste things exactly as they are?? Why is terminal behaving this way?
What happens when you use pbcopy?
samtools view sorted-616.bam | grep 'SOLEXA9:1:1:30:3316:10211' | head -n 1 | pbcopy
This should do the same thing that the copy command does, but without having to select the output you want.
Have you tried another terminal emulator? I use iTerm2 because it will copy to the clipboard on selection without having to hit Command-c.
EDIT: You may have to install Apple's developer tools to get the pbcopy/pbpaste tools.
No idea why the spaces are missing from the pasted text, but I'd try to write the output to a file, open up the file in an editor and try to see if it's something other than the standard space/newline characters. You seem to know your way with piping, but anyway:
samtools view sorted-616.bam | grep 'SOLEXA9:1:1:30:3316:10211' | head -n 1 > file.txt
It might depend on which system the host is running. I have had some issues while on ssh connections to linux/unix hosts, while Mac-to-Mac usually works just fine.
Related
Note: I am particularly looking for a coding hack, not for an alternative solution. I am aware that awk, sed etc. can do this inline edit just fine.
$ echo '1' > test
$ cat test > test
$ cat test
$
Is there a way, to somehow make the second command output the original contents (1 in this case)? Again, I am looking for a hack which will work without visibly having to use a secondary file (using a secondary file in the background is fine). Another question on this forum solely focused on alternative solutions which is not what I am looking for.
You can store the content in a shell variable rather than a file.
var=$(<test)
printf "%s\n" "$var" > test
Note that this might only work for text files, not binary files. If you need to deal with them you can use encoding/decoding commands in the pipeline.
You can't do it without storing the data somewhere. When you redirect output to a file, the shell truncates the file immediately. If you use a pipeline, the commands in the pipeline run concurrently with the shell, and it's unpredictable which will run first -- the shell truncating the file or the command that tries to read from it.
With thanks to the comment made by #Cyrus to the original question
$ sudo apt install moreutils
$ echo '1' > test
$ cat test | sponge test
$ cat test
1
It does require installing an extra package and pre-checking for the binary using something like where sponge to check if it is installed.
if you happen to use macos, if the file isn't too gargantuan, you can always follow these steps :
perform the edits
pipe it to the clipboard (or "pasteboard" in mac lingo)
paste it back to original file name
|
{... edits to file1 ...} | pbcopy; pbpaste > file1
I am using a CLI application that prints \u001Bc to the terminal to clear the screen. This application is not interactive, though, and I would like to see all of its output. Is there a way to prevent this application from clearing the screen without altering its source code?
I attempted to use app | grep -v '\u001Bc' but this doesn't appear to work, and it would also filter out the entire line containing \u001Bc even if it did work.
You can try removing the Esc + c via sed
application | sed 's/\x1bc//g'
I'm trying to integrate PVS-Studio analysis into CI for my homework. Everything seems to work fine except log printing; I want warnings to be colored or highlighted in some other way.
The best I could think of is to use plog-converter to output in html format and then use elinks -dump -dump-color-mode 1 to output that in terminal but it looks kinda weird.
Is there a better way to do it?
I think the best way is to modify the source of the plog-converter. The source code of the utility is published on GitHub so that users can expand the functionality for their tasks.
Since plog-converter can't do it out of the box and modifying its source code is a bit extreme, I decided to highlight output myself.
After a bit of a fiddling with syntax highlighting in terminal I found out that the simplest way is just using grep kinda like this:
plog-converter -t errorfile project.log | \
GREP_COLOR='01;31' grep -E --color=always 'error:|$' | \
GREP_COLOR='01;33' grep -E --color=always 'warning:|$'
I suppose errorfile format should only containt "errors" and "warning" so this colorizes just these two words with two different colors
I'm writing a small program that prints to the terminal its output in tab separated format. But whenever I select the text with tabs and copy it, the tabs are replaces with some number of spaces.
What can I do to make terminal not replace tabs with spaces when trying to copy?
On macOS Sierra (maybe also in earlier versions), you can do:
Edit -> Copy Special -> Copy Plain Text
Or using the shortcut:
alt+shift+⌘ cmd+C
Your best bet may be to substitute "\t" in place of tabs in your output, and do a search and replace after you copy and paste it to the destination.
You could use any character or string as the substitute, of course, but using "\t" makes it easy to restore the tabs using echo -e if pasting to a command-line environment.
The substitution can be done using: |sed 's/\\/\\\\\\/g;s/\t/\\t/g'
I am able to do it on my mac terminal. Here are some good tests:
printf '>\t<\n' : works (copies into sublime as a tab; selecting it only lets me select the full tab not individual spaces)
printf '>\t<\n' | less : fails
printf '>\t<\n' | more : fails
printf '>\t<\n' | less | cat : works (less detects output is file/pipe not terminal so no terminal settings applied)
printf '>\t<\n' | less | cat -vet : outputs ">^I<$" (less detects pipe output so no terminal settings applied)
printf '>\t<\n' | vi - : fails but when I move in vi, it jumps across the tab in 1 keypress so it knows it is a tab
reset : from now on, it always fails
stty -tabs : from now on, it always fails
stty tabs : fixes the reset/stty -tabs problem, now it can work again
One guy got less to work by altering the source: https://unix.stackexchange.com/questions/412060/how-to-get-less-to-show-tabs-as-tabs
less related options: '-U' shows tabs as '^I', '-x4' sets tab size
For git diff:
git diff | head -40 : works (copies into sublime with tabs)
git diff | cat : works
git diff | less : fails (less applies terminal settings)
git diff : fails (my git pager is less)
I monitor a file for changes in a separate thread using kqueues/ kevent(2).
(I monitor a Python file for reparsing)
I subscribe as following:
EV_SET(&file_change, pyFileP, EVFILT_VNODE,
EV_ADD | EV_CLEAR,
NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND |
NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | NOTE_REVOKE,
0, 0);
When I write to the file "/tmp/somefile.py" using Vim, I get two separate kevents:
The flags of these events (event.fflags) are:
NOTE_RENAME
and
NOTE_DELETE | NOTE_LINK
I never get a "NOTE_WRITE" event!
This seems to have something to do with the way Vim writes these files, since if I do
echo "sometext" >> /tmp/somefile.py
I do get the:
NOTE_WRITE|NOTE_EXTEND
event.
Odd, eh? I haven't checked the Vim source code but it must do something strange, or does it simply use user level functions that are implemented that way?
I wasn't really expecting this. Is this a known problem, I just have to check for all events possible, or is there a known interface that really checks if a file has been written?
What is actually happening is that Vim won't write over the same file, first
it probably renames it to something else and then creates another file (link).
You can confirm that by doing something like:
$ vim file -c wq
This will open a file and write it. Now check the inode:
$ ls -i
30621217 file
Write the file with Vim again and re-check the inode:
$ vim file -c wq
$ ls -i
30621226 file
It's just different. That means the second file is actually another file
(linked to another inode) with the same name, and the old one was unlinked.
Many editors do that. I can't confirm why exactly Vim takes this approach.
Maybe for safety: if you first rename the file and something goes wrong
while writing the new file, you still have the old one. If you start writing
over a file and a problem occurs (even with memory) you'll probably loose part
of it. Maybe.