I have a program that generates and outputs a sequence of simple sample math homework tasks, like:
1 + 1 = ...
3 + 3 = ...
2 + 5 = ...
3 + 7 = ...
4 + 2 = ...
a sequence can be quite long, and I'd like to save space when this sequence is printed by converting it as follows:
1 + 1 = ... 3 + 7 = ...
3 + 3 = ... 4 + 2 = ...
2 + 5 = ...
that is, wrapping the lines into the two or more columns. I was expecting the column linux utility to do the job using the -c N option witn N=2, however, it still outputs the lines in one column whatever the N is.
How would I do the column-ifying of the sequence of lines?
Believe it or not, the utility you want is pr, not columns. If you want your file turned into 3 columns:
pr -3 textfile.txt
If you want to fill in rows first, then columns:
pr -l1 -t -3 textfile.txt
I got these sample invocations from the ever-so-useful UNIX Power Tools. This is Recipe 21.16.
The -c parameter to column is used to specify the number of "columns" your display has, counted in characters. The column tool then figures out the number of "output columns" that fits in the given number of "character columns". Passing a small number of "character columns" will almost always yield a single "output column", because more won't fit in the given number of characters. There does not seem to be a way to pass the number of ouput columns on the command line.
Related
Here's my question. I'm using Lua and I have a string that looks something like this:
"Start1.2.3.4.5-1.2.3.4.5-1.2.3.4.5-1.2.3.4.5-1.2.3.4.5End"
The five numbers between each hyphen are all paired to the same "object" but each represents a separate set of data. The period between the numbers separates the data.
So after Start, 1 = our first value, 2 = our second value, 3 = our third value, 4 = our fourth value, and 5 = our fifth value. These 5 values are stored to the same object. Then we hit our first hyphen which separates the "objects". So there's 5 objects and 5 values per object.
I used 1.2.3.4.5 as an example but these numbers will be randomized with up to 4 digits. So it could say something like Start12.3.100.1025.50- etc...
Hopefully that makes sense. Here's what I have done so far:
MyString = the long string I posted above
local extracted = string.match(MyString, "Start(.*)")
This returns everything beyond Start in the string. However, I want it to return everything after Start and then cut off once it reaches the next hyphen. Then from that point on I'll repeat the process but instead find everything between the hyphens until I reach End. I also need to filter out the periods. Also, the hyphens/periods can change to something else as long as they aren't numbers.
Any ideas on how to do this?
Just use a pattern that captures anything that contains numbers and periods.
"([%d%.]+)" Note that you have to escape the period with % as it is a magic character.
local text = "Start1.2.3.4.5-1.2.3.4.5-1.2.3.4.5-1.2.3.4.5-1.2.3.4.5End"
for set in text:gmatch("([%d%.]+)") do
print(set)
local numbers = {}
for num in set:gmatch("%d+") do
table.insert(numbers, num)
end
print(table.unpack(numbers))
end
prints:
1.2.3.4.5
1 2 3 4 5
1.2.3.4.5
1 2 3 4 5
1.2.3.4.5
1 2 3 4 5
1.2.3.4.5
1 2 3 4 5
1.2.3.4.5
1 2 3 4 5
I want to read some values from a file called Input.txt. The input file looks like this:
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
....
in total its 36 lines of 1,2,3 and 4s
then I use the following code to read from the file:
program outputtest
implicit none
double precision, allocatable, dimension(:) :: A,B,C,D
integer :: counter,ii, ierror
ierror=0
counter=1
open(39, action='read', name='input.txt', status='old')
do
read(39,100, IOSTAT=Ierror)
100 Format(T8,I1)
If (Ierror>0) then
print *, 'error when reading'
stop
end if
If (ierror<0) then
print*, 'end of file reached'
exit
end if
counter=counter+1
end do
If (.not.allocated(A)) ALLocate(A(counter))
If (.not.allocated(b)) ALLocate(b(counter))
If (.not.allocated(c)) ALLocate(c(counter))
If (.not.allocated(d)) ALLocate(d(counter))
do ii=1, counter-1
read(39,110, IOSTAT=ierror) A(ii), B(ii), C(ii), D(ii)
110 Format(T8, I4, T16, I4, T24, I4, T32, I4)
If (ierror.neqv.0) exit
end do
close(39)
write (*,120) A
write (*,120) B
write (*,120) C
write (*,120) D
120 Format('result:', 1x,I2)
end program outputtest
The problem is now that the A,B,C,D are all equal to zero, i.e. my output is:
result: 0
result: 0
result: 0
....
This means that I do not read either from the correct lines or I make another mistake. I used in vim the option ruler to see what lines those entries are in and used those lines together with T. I created the file Input.txt by using tabs. What is my mistake?
A two things:
You don't do a rewind in your file. At first you read through the whole file to get the number of lines, but without a rewind, you start reading at the end -- which means nothing gets actually read into the arrays.
read with explicit formats is dangerous. You have to be really certain that the input file matches the format precisely. In your case, I'd to as #high-performance-mark suggested and use fmt=*. Your input file should easily be read automatically.
That's what I can gleam from a quick browse. See if that helps.
(1:)`(3:)#.(1&=)"0 i.2
1 3
(1:,2:)`(3:)#.(1&=)"0 i.2
1 2
3 0
I want to get
1 2 3
Without new dimensions. Without zeros.
The shape changes dramatically between (1:) and (1:,2:).
$ 1: 'a'
$ 1 $ 1: 'a'
1
$ (1:,2:) 'a'
2
(1&$ 1:)`(1&$ 3:)#.(1&=)"0 i.2
1
3
There's probably a better way, but to my way of thinking, you're generating arrays of unequal length, which should be boxed, and then you want to turn them into a single list.
Thus:
; ((1:,2:)`(3:))#.(1&=)"0&.> i.2
1 2 3
Which can be refactored and improved a bit:
;#:((1:,2:)`(3:)#.(1&=)each) i.2
1 2 3
You could have used (1:,2:,3:) 'ignored argument' to form the list, but that doesn't address why you were using #.
Dane's comment about boxing intermediate results and then razing the resulting list is relevant if you want to merge irregularly shaped results. (Which might be what you were trying for, here.)
I have the following data.frame:
employee <- c('John Doe','Peter Gynn','Jolie Hope')
# Note that the salary below is in stringified format.
# In reality there are more such stringified numerical columns.
salary <- as.character(c(21000, 23400, 26800))
df <- data.frame(employee,salary)
The output is:
> str(df)
'data.frame': 3 obs. of 2 variables:
$ employee: Factor w/ 3 levels "John Doe","Jolie Hope",..: 1 3 2
$ salary : Factor w/ 3 levels "21000","23400",..: 1 2 3
What I want to do is to convert the change the value from string into pure number
straight fro the df variable. At the same time preserve the string name for employee.
I tried this but won't work:
as.numeric(df)
At the end of the day I'd like to perform arithmetic on these numeric
values from df. Such as df2 <- log2(df), etc.
Ok, there's a couple of things going on here:
R has two different datatypes that look like strings: factor and character
You can't modify most R objects in place, you have to change them by assignment
The actual fix for your example is:
df$salary = as.numeric(as.character(df$salary))
If you try to call as.numeric on df$salary without converting it to character first, you'd get a somewhat strange result:
> as.numeric(df$salary)
[1] 1 2 3
When R creates a factor, it turns the unique elements of the vector into levels, and then represents those levels using integers, which is what you see when you try to convert to numeric.
I prompt the user to input a variable 'year'.
I need to get the first 2 digits, and the last 2 digits of the 4-digit variable year for the Gaussian algorithm and store them in two separate variables.
What I need help on is getting the first 2 and last 2 numbers from 'year'.
Try this:
local n = 1234
local first = math.floor(n / 100)
local last = n % 100
print(first, last)
which print:
12 34
To add to Bart's answer, if you're keeping it in string form you can just use sub to grab the parts you want:
year = '1969'
firsttwo = year:sub(1,2)
secondtwo = year:sub(3,4)