Please explain this BASH command "cat /y//.ssh/id_rsa.pub" - bash

What does this command mean?
cat /y//.ssh/id_rsa.pub
I know that cat is a concatenate command and .ssh/id_rsa.pub is probably the target file id_rsa.pub in directory .ssh
But what is the /y// all about?
I don't know bash, well out of my comfort zone and when I try to display help, it doesn't help (me):
$ cat --help
Usage: cat [OPTION]... [FILE]...
Concatenate FILE(s) to standard output.
With no FILE, or when FILE is -, read standard input.
-A, --show-all equivalent to -vET
-b, --number-nonblank number nonempty output lines, overrides -n
-e equivalent to -vE
-E, --show-ends display $ at end of each line
-n, --number number all output lines
-s, --squeeze-blank suppress repeated empty output lines
-t equivalent to -vT
-T, --show-tabs display TAB characters as ^I
-u (ignored)
-v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
--help display this help and exit
--version output version information and exit
Examples:
cat f - g Output f's contents, then standard input, then g's contents.
cat Copy standard input to standard output.
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Report any translation bugs to <https://translationproject.org/team/>
Full documentation <https://www.gnu.org/software/coreutils/cat>
or available locally via: info '(coreutils) cat invocation'

Related

How to treat files as huge string with macos grep?

I'm using the following command on Ubuntu to list all files containing a given pattern:
for f in *; do if grep -zoPq "foo\nbar" $f; then echo $f; fi; done
But on macos, I'm geting the following error:
grep: invalid option -- z
There's no -z option to treat files as a big string with macos grep, unlike gnu grep.
Is there another option on macos grep equivalent to `-z ? If not, what alternative can I use to get the same result ?
-P (PERL regex) is only supported in gnu grep but not on BSD grep found on Mac OS.
You can either use home brew to install gnu grep or else use this equivalent awk command:
awk 'p ~ /foo$/ && /^bar/ {print FILENAME; nextfile}; {p=$0}' *
Please note that this eliminates the need to use shell for loop.
You can install pcregrep via home brew, and then use it with the -M option:
By default, each line that matches a pattern is copied to the
standard output, and if there is more than one file, the file name is
output at the start of each line, followed by a colon. However, there
are options that can change how pcregrep behaves. In particular, the
-M option makes it possible to search for patterns that span line
boundaries. What defines a line boundary is controlled by the -N
(--newline) option.
With ripgrep
rg -lU 'foo\nbar'
This will list all filenames containing foo\nbar in the current directory. -U option allows to match multiple lines. Unlike grep -z, whole file isn't read in one-shot, so this is safe to use even for larger input files.
ripgrep recursively searches by default. Use rg -lU --max-depth 1 'foo\nbar' if you don't want to search sub-directories.
However, note that by default, rigprep ignores
files and directories that match rules specified by ignore files like .gitignore
hidden files and directories
binary files
You can change that by using:
-u or --no-ignore
-uu or --no-ignore --hidden
-uuu or --no-ignore --hidden --binary
It seems you are searching for files which have the sequence foo\nbar. With GNU awk (brew install gawk), you can set the record separatorRS to this sequence and check if the record matches:
gawk 'BEGIN{RS="foo\nbar"}{exit (RT!=RS)}' file
This will try to split your files in records which are separated by the record separator RS, if so, it will terminate with exit code 0, otherwise with exit code 1. The behaviour is the same as the proposed grep
If you just want the files listed, you can do:
gawk 'BEGIN{RS="foo\nbar"}(RT==RS){print FILENAME}{nextfile}' *

some arguments not work from AppleScript to grep thru do shell script

in applescript editor:
do shell script "grep -w 'SomeText' /tmp/test"
ignores -w
in Bash:
grep -w 'SomeText' /tmp/test
not ignores arguments
But for example arguments -v (negative) works in AppleScript with do shell script
it is happening on both different computers with different systems
how i can use -w argument in grep from applescript?
Thanks!
Regardless of where I run the grep -w ... command from, Terminal or ApplesScript's do shell script command, I get identical output.
The manual page for the -w option in grep states the following:
−w, −−word-regexp
The expression is searched for as a word (as if surrounded by ‘[[:<:]]’ and ‘[[:>:]]’; see re_format(7)).
The manual page for re_format states:
There are two special cases‡ of bracket expressions: the bracket expressions [[:<:]] and [[:>:]] match the null string at the beginning and end of a word respectively. A word is defined as a sequence of word characters which is neither preceded nor followed by word characters. A word character is an alnum character (as defined by ctype(3)) or an underscore.
In Terminal:
Contents of /tmp/test:
$ cat /tmp/test
SomeText
MoreText
ASomeTextZ
Other Text
0 SomeText 1
$
Using grep without -w on /tmp/test:
$ grep 'SomeText' /tmp/test
SomeText
ASomeTextZ
0 SomeText 1
$
As it should, grep finds all three lines containing 'SomeText'.
Using grep with -w on /tmp/test:
$ grep -w 'SomeText' /tmp/test
SomeText
0 SomeText 1
$
As it should, grep -w finds only the lines conforming to what's stated in the manual page excerpts shown above. In this case, only two of the three lines that contain 'SomeText'.
The output of each grep command, show above, when wrapped in a do shell script command in AppleScript are identical, as should be.
In Script Editor:
Because these are the expected results is why I'm adamant about following How to create a Minimal, Complete,and Verifiable example, when asking questions such that you have, in the manner you have!
I'd suggest you show us the actual content of your /tmp/test file and the actual output you get from each of the grep commands, with and without the -w option, from both Terminal and AppleScript's do shell script command.
Although it shouldn't make a difference, nonetheless you should also provide macOS version info so we can test this under the actual version of macOS you're using, so as to see if that's a relevant factor in the equation.

How to order ls command display in numerical order?

I created 3 files in a directory with the following names:
11 13 9
Problem, as I created file 9 after 13 it is placed after file 13 when I do the ls command.
Do you have any idea to make the ls command sort the files in the numerical order, like this:
9 11 13
Look at the man page for ls.
From there-
-v natural sort of (version) numbers within text.
You'll find that the command ls -v does what you want.
If you want the file names on different lines then you can do ls -1v.
List with lines without columns:
ls -x
Using tr to avoid multiple lines output:
ls | tr "\n" " "
And to ensure to accurately force ascending order:
ls -v | tr "\n" " "
Some useful and essential information from linux.org about ls.
Unfortunately, ls -v on macOS and FreeBSD does not perform a natural sort on the list of files. FreeBSD ls does not support this flag at all. On macOS it can be used to
force unedited printing of non-graphic characters; this is the default when output is not to a terminal.
If you badly need the GNU extension of -v to the ls utility, you can install the GNU ls and then use alias ls=gls to use the GNU ls instead of the default ls. GNU ls usually comes with the coreutils package, so, e.g.,
On macOS: brew install coreutils
On FreeBSD: pkg install coreutils

GNU 'ls' command not outputing the same over a pipe [duplicate]

This question already has answers here:
Why does ls give different output when piped
(3 answers)
Closed 6 years ago.
When I execute the command ls on my system, I get the following output:
System:~ user# ls
asd goodfile testfile this is a test file
However, when I pipe ls to another program (such as cat or gawk), the following is output:
System:~ user# ls | cat
asd
goodfile
testfile
this is a test file
How do I get ls to read the terminal size and output the same over a pipe as it does when printing directly to the terminal?
This question has been solved.
Since I'm using bash, I used the following to achieve the desired output:
System:~ user# ls -C -w "$(tput cols)" | cat
Use ls -C to get columnar output again.
When ls detects that its output isn't a terminal, it assumes that its output is being processed by some other process that wants to parse it, so it switches to -1 (one-entry-per-line) mode to make parsing easier. To make it format in columns as when it's outputting directly to a terminal, use -C to switch back to column mode.
(Note, you may also have to use --color if you care about color output, which is also normally suppressed by outputting to a pipe.)
Maybe -x "list entries by lines instead of by columns" with possible -w "assume screen width instead of current value" is what you need.
When the output goes to a pipe or non-terminal, the output format is like ls -1. If you want the columnar output, use ls -C instead.
The reason for the discrepancy is that it is usually easier to parse one-line-per-file output in shell scripts.
Since I'm using bash, I used the following to achieve the desired output:
System:~ user# ls -C -w "$(tput cols)" | cat

wc output differs inside/outside vim

I'm working on a text file that contains normal text with LaTeX-style comments (lines starting with a %). To determine the non-comment word count of the file, I was running this command in Bash:
grep -v "^%" filename | wc -w
which returns about the number of words I would expect. However, if from within vim I run this command:
:r! grep -v "^%" filename | wc -w
It outputs the word count which includes the comments, but I cannot figure out why.
For example, with this file:
%This is a comment.
This is not a comment.
Running the command from outside vim returns 5, but opening the file in vim and running the similar command prints 9.
I also was having issues getting vim to prepend a "%" to the command's output, but if the output is wrong anyways, that issue becomes irrelevant.
The % character is special in vi. It gets substituted for the filename of the current file.
Try this:
:r! grep -v "^\%" filename | wc -w
Same as before but backslash-escaping the %. In my testing just now, your example :r! command printed 9 as it did for you, and the above printed 5.

Resources