I want to count the number of lines generated by a command substitution $(blah) using zsh instead of piping through wc -l. I know how to turn the command substitution lines into an array, like this:
blah_output=(${(f)"$(blah)"})
…and counting the number of items in an array is just this:
${#blah_output}
My question is: how can I do that in one expression, without the intermediate variable? After some fiddling, I came up with this:
${#${(f)"$(blah)"}}
…which works unless blah returns only one line, at which point it returns the number of characters in that line, and I don't understand why or how to fix it. What's the real answer? Is there one?
Sub-questions:
When creating the initial array, I don't understand why the outer parentheses are necessary; I expected that splitting would imply an array value.
I don't understand why the quotes around $(blah) are necessary; if I don't include them, I get one element with the line break transformed into a space. Something about an implicit word split and then join?
Related
I have a long character that comes from a pdf that I want to process.
I have recurring instances of Table X. Name of the table, that in my character are always followed by a \r\n
However, when I try to extract all the tables in a list, using List_Tables <-str_extract_all(Plain_Text, "Table\\s+\\d+\\.\\s+(([A-z]|\\s))+\\r\\n"), I do have often another line that is still in my extraction, e.g.
> List_Tables
[[1]]
[1] "Table 1. Real GDP\r\n Percentage changes\r\n"
[2] "Table 2. Nominal GDP\r\n Percentage changes\r\n"
What have I missed in my code ?
\s matches all whitespace, including line breaks! When combined with the greedy quantifier +, this means that (([A-z]|\\s))+ matches, in your first example,
Real GDP\r\n […] Percentage changes\r\n
The easiest way to fix this is to use a non-greedy quantifier: i.e. +? instead of +.
Just for completeness’ sake I’ll mention that there are alternatives, but they get more complicated. For instance, you could use negative assertions to include an “if” test to match whitespace which isn’t a line break character; or you could use the character class [ \t] instead of \s, which is more restrictive but also more explicit and probably closer to what you want.
Example:
Log To Console This is the first argument This is the second argument This is the third argument
How can I break a line with multiple short arguments?
I tried using \ or just breaking the lines (without using any special characters) but it didn't work.
Edit: To clarify - I want to provide arguments to a keyword in multiple lines. I want to physically split one long line of source code into multiple short lines.
From the User Guide:
If there is more data than readily fits a row, it possible to use ellipsis (...) to continue the previous line.
Example test [Documentation] Documentation for this test case.
... This can get quite long...
Do X one two three
... four five six
To keep it simple, consider following task:
Given a non-empty shell variable var, where we know that the last character is the letter a and that at least one character is not an a, remove all the a from the right of the variable.
Example: If the variable initially contains abcadeaaa, it should contain abcade afterwards.
I wondering whether this can be done in a compact way in Zsh.
Of course this is trivial to do using an external program (such as sed), or by using a while loop, where we consecutively strip the last a (${VAR%a}), until the value of the variable doesn't change anymore. Both would work in a POSIX shell, in bash or in ksh. However, given that Zsh has so many nice features for expansion, I wonder, whether there isn't a better way.
The problem is that matching a run of a certain character (independend of length) cries out for regular expressions, but the pattern after % in parameter expansion, and the pattern in the s/// substitution, both is a wildcard pattern, which doesn't allow me to do what I want - at least according to my understanding of the zshexpn man page.
Any ideas for this?
Note that this question is not to solve a real-world problem (in which case I simply would use sed to do the job, as this would get the job done), but more out of academic interest, to find out how far we can stretch the limits of the Zsh expansion mechanism.
Alright, I've been given a program that requires me to take a .txt file of varying symbols in rows and columns that would look like this.
..........00
...0....0000
...000000000
0000.....000
............
..#########.
..#...#####.
......#####.
...00000....
and using command arguments to specify row and column, requires me to select a symbol and replace that symbol with an asterisk. The problem i have with this is that it then requires me to recur up, down, left, and right any of the same symbol and change those into an asterisk.
As i understand it, if i were to enter "1 2" into my argument list it would change the above text into.
**********00
***0....0000
***000000000
0000.....000
............
..#########.
..#...#####.
......#####.
...00000....
While selecting the specified character itself isn't a problem, how do i have any similar, adjacent symbols change and then the ones next to those. I have looked around but can't find any information and as my teacher has had a different subs for the last 3 weeks, i havent had a chance to clarify my questions with them. I've been told that recursion can be used, but my actual experience using recursion is limited. Any suggestions or links i can follow to get a better idea on what to do? Would it make sense to add a recursive method that takes the coordinates given adds and subtracts from the row and column respectively to check if the symbol is the same and repeats?
Load in char by char, row by row, into a 2D array of characters. That'll make it a lot easier to move up and down and left and right, all you need to do is move one of the array indexes.
You can also take advantage of recursion. Make a function that changes all adjacent matching characters, and then call that same function on all adjacent matching characters.
I have a very long expression that I need to take the derivative of:
D(expression(-4750000+(((14400*(((x/25)*1)-7.2))+(0*((x*1.05)-7.2))+(144*
((x*0.6)-7.2))*30.41667)-2500)/((0.1+1)^((1-0.5)/12))+(((13216.5802942644*
(((x/25)*1)-7.2))+(0*((x*1.05)-7.2))+(132.165802942644*
((x*0.6)-7.2))*30.41667)-2500)/((0.1+1)^((2-0.5)/12))+.........),'x')
When the expression is less than 4000 characters I get a solution. When it is more than 4000 characters, R gives me a newline and +, expecting more input. I haven't been able to find documentation on a character limit. Does anyone know why this might be? Any workarounds or alternatives to finding this derivative? The final character length will be at least 50k.
You are probably seeing an effect of input through stdin which uses the OS newline function. Try putting it in a text file and source()-ing.