Print the last field using 'cut' [duplicate] - shell

This question already has answers here:
How to find the last field using 'cut'
(14 answers)
Closed 6 years ago.
Let's say I've the following data:
ae722d1d94dcd3b161af166936:!]z#.:123
09338b2b29919e6c0daefbcce0361335:21f2e48d86f28ab7cd5c9c95:123
$H$92Gh.gRJwECLPzkjACPihoLg/:123
c6f1cb5f1feeece60f9a8e067e0:v4Zz'Cj5_Ze{J+iRW{2z,<~:123
202cb962a75b964b07152d234b70:123
40bd0015630c35165329ea5ecbdbbeef:123
(Invaild hashes, for explaining purpose only)
I want to use the cut tool in printing the last field only.
123
123
123
123
123
123
I don't want to use rev command.
I want nothing other than cut, I know how to do it in sed, awk.
--complement flag might help!

For that specific data you can:
cut -f2- -d: file | cut -f2 -d:
If you might have three colons:
cut -f2- -d: file | cut -f2- -d: | cut -f2 -d:
You can keep adding more cuts as needed.
The trick is that cut does nothing to a record that doesn't have the delimiter so you can use successive cuts to chop off the first field while leaving the last fields that you've already found alone.

i saw this on another place when I was looking for this answer.
rev, cut (on delimiter) -f 1, rev
move the last field forward, cut it, and move it back
i thought that was kinda slick

Related

Extracting UUID string from a text using shell script commands

I have a text line as:
host_id -------------------------------------- f5f4d3e7-fdc4-49f2-b32c-13280bc7db66 (1 rows)
And I want to extract only the UUID value within the text using shell script as I need to run this on ubuntu to execute some other commands using the value. I tried using cut command:
cut -d '-' -f2 | cut -d '(' -f1
But couldn't succeed to specify the cut character for before and after of the UUID string.
The problem using cut -d'-' in your case is that the field (-f) values you will have to add is not 2 but 38 and above (that's the number of consecutive - symbols in your string), because of how cut works. This is the output you will get if you just set the field 39 (using cut -d'-' -f39):
f5f4d3e7
But also the UUID string you want contains additional hyphens, so if you still want to get it that way (using cut) you will have to expand your field selection, in this case by adding -f39-43. But that just will not solve the problem of showing the string "(1 rows)" after it, so by running cut -d'-' -f39-43 you will get this:
f5f4d3e7-fdc4-49f2-b32c-13280bc7db66 (1 rows)
And that's why you used a second cut filter to just pick the UUID value string. While this is okay, it seems to be pretty much handy using awk, which will solve all these problems in one single command:
cat file.txt | awk '{ print $3 }'
Or if your string is not coming from a file:
echo "host_id -------------------------------------- f5f4d3e7-fdc4-49f2-b32c-13280bc7db66 (1 rows)" | awk '{ print $3 }'

If I do not know the number of words in a line then how do I use cut such a way that I get the last word? [duplicate]

This question already has answers here:
How do I get the last word in each line with bash
(7 answers)
Closed 3 years ago.
for a file file.txt, the contents are:
Had repulsive dashwoods suspicion sincerity but advantage now him.
Remark easily garret nor nay.
Civil those mrs enjoy shy fat merry. You greatest jointure saw horrible.
He private he on be imagine suppose.
Fertile beloved evident through no service elderly is.
Now I want to cut such a way that I only get the last words of the lines
I tried
cut -d" " -f1- file.txt
but that just gives all from start to end.
cut -d" " -f-1 file.txt
This just gives the first word.
You can do that easily with awk:
echo "Hi there Zeeshan." | awk '{print $NF}'
would print Zeeshan.
For your file:
awk '{print $NF}' file.txt

Shell: Counting lines per column while ignoring empty ones

I am trying to simply count the lines in the .CSV per column, while at the same time ignoring empty lines.
I use below and it works for the 1st column:
cat /path/test.csv | cut -d, -f1 | grep . | wc -l` >> ~/Desktop/Output.csv
#Outputs: 8
And below for the 2nd column:
cat /path/test.csv | cut -d, -f2 | grep . | wc -l` >> ~/Desktop/Output.csv
#Outputs: 6
But when I try to count 3rd column, it simply Outputs the Total number of lines in the whole .CSV.
cat /path/test.csv | cut -d, -f3 | grep . | wc -l` >> ~/Desktop/Output.csv
#Outputs: 33
#Should be: 19?
I've also tried to use awk instead of cut, but get the same issue.
I have tried creating new file thinking maybe it had some spaces in the lines, still the same.
Can someone clarify what is the difference? Betwen reading 1-2 column and the rest?
20355570_01.tif,,
20355570_02.tif,,
21377804_01.tif,,
21377804_02.tif,,
21404518_01.tif,,
21404518_02.tif,,
21404521_01.tif,,
21404521_02.tif,,
,22043764_01.tif,
,22043764_02.tif,
,22095060_01.tif,
,22095060_02.tif,
,23507574_01.tif,
,23507574_02.tif,
,,23507574_03.tif
,,23507804_01.tif
,,23507804_02.tif
,,23507804_03.tif
,,23509247_01.tif
,,23509247_02.tif
,,23509247_03.tif
,,23527663_01.tif
,,23527663_02.tif
,,23527663_03.tif
,,23527908_01.tif
,,23527908_02.tif
,,23527908_03.tif
,,23535506_01.tif
,,23535506_02.tif
,,23535562_01.tif
,,23535562_02.tif
,,23535636_01.tif
,,23535636_02.tif
That happens when input file has DOS line endings (\r\n). Fix your file using dos2unix and your command will work for 3rd column too.
dos2unix /path/test.csv
Or, you can remove the \r at the end while counting non-empty columns using awk:
awk -F, '{sub(/\r/,"")} $3!=""{n++} END{print n}' /path/test.csv
The problem is in the grep command: the way you wrote it will return 33 lines when you count the 3rd column.
It's better instead to use the following command to count number of lines in .CSV for each column (example below is for the 3rd column):
cat /path/test.csv | cut -d , -f3 | grep -cve '^\s*$'
This will return the exact number of lines for each column and avoid of piping into wc.
See previous post here:
count (non-blank) lines-of-code in bash
edit: I think oguz ismail found the actual reason in their answer. If they are right and your file has windows line endings you can use one of the following commands without having to convert the file.
cut -d, -f3 yourFile.csv cut | tr -d \\r | grep -c .
cut -d, -f3 yourFile.csv | grep -c $'[^\r]' # bash only
old answer: Since I cannot reproduce your problem with the provided input I take a wild guess:
The "empty" fields in the last column contain spaces. A field containing a space is not empty altough it looks like it is empty as you cannot see spaces.
To count only fields that contain something other than a space adapt your regex from . (any symbol) to [^ ] (any symbol other than space).
cut -d, -f3 yourFile.csv | grep -c '[^ ]'

shell script to extract text from a variable separated by forward slashes

I am trying to find a way to to extract text from a variable with words separated by a forward slash. I attempted it using cut, so here's an example:
set variable = '/one/two/three/four'
Say I just want to extract three from this, I used:
cut -d/ -f3 <<<"${variable}"
But this seems to not work. Any ideas of what I'm doing wrong? Or is there a way of using AWK to do this?
You need to remove the spaces before and after to = during string or variable assignment. And tell the cut command to print the 4th field.
$ variable='/one/two/three/four'
$ cut -d/ -f4 <<<"${variable}"
three
With the delimiter /, cut command splits the input like.
/one/two/three/four
| | | | |
1 2 3 4 5
that is, when it splits on first slash , you get an empty string as first column.
I think that the main problem here is in your assignment. Try this:
var='/one/two/three/four'
cut -d/ -f4 <<<"$var"
Here is an awk version:
awk -F\/ '{print $4}' <<< "$variable"
three
or
echo "$variable" | awk -F\/ '{print $4}'
three
PS to set a variable not need for set and remove spaces around =
variable='/one/two/three/four'

cut command to retrieve 2nd part of words

i have a few name that I need to cut out and get the 2nd part of the name
agent-tom
agent-harry
agent-disk-see
I used cut -d "-" -f2
I only manage to get "tom", "harry" and "disk"
question: how do I use the cut command in order to cut the 3rd agent so that i could get "disk-see" ??
Thanks
cut -d '-' -f 2-
Cuts from 2nd column to end and will get all regardless of dash count.
Adapted from Wikipedia:
To output the second field through the end of the line of each line using the "-" character as the field delimiter:
cut -d "-" -f 2- file
If you're willing to consider tools other than cut:
pax> sed 's/^[^-]*-//' inputFile
tom
harry
disk-see
This command uses the stream editor sed to remove the part of the line from the start up to the first - character. I generally prefer sed for tasks like these since it's more adaptable when doing things other than simple one-level-deep field manipulations.
Having said that, this is a fairly simple task so a slight modification to your cut command will suffice. Simply use -f2- (field 2 onwards) in place of -f2 (field two only):
pax> cut -d'-' -f2- inputFile
tom
harry
disk-see

Resources