-1

I have this assignment

The FILE variable is the name of a text file that contains exactly 30 lines. Each line consists of just one word, consisting of uppercase and lowercase letters and numbers.

Change this file so that all digits disappear from the words, all letters change to lowercase, and the modified words are sorted alphabetically in ascending order. The modified file will have the format of three columns of separate tables, where the first column will contain the first 10 words after sorting, the second column the second 10 and the rest the third. Number the lines of the file.

input:

hUeY65u
9sjKdfh
A56oi4
22cfe4HW
Gws6K
zh71p6t
...

output:
     1  aoi     gwsk    sjkdfh
     2  cfehw   hueyu   zhpt
     ...

I created this script, it works for me, but not on the school server. You don't know where the problem might be. Thank you

cat $FILE | tr '[:upper:]' '[:lower:]' | tr -d "[0-9]" | sort >file1.txt;  
split -l 10 file1.txt; paste xaa xab xac >file2.txt; nl file2.txt; 



    Stderr mismatch:
-----expected-----

--------got-------
/home/blxrpcdcgb/Student: line 1: $FILE: ambiguous redirect
paste: xaa: No such file or directory

------------------
'"$HOME"/file1.txt' is excessive.
'"$HOME"/file2.txt' is excessive.
'"$HOME"/kfekd  jojny' has incorrect content:
-----expected-----
     1  azkxbj  ikrmp   rynlv
     2  bledfoa jttknol sipei
     3  cdquayr jxphn   tatuqun
     4  csglb   llnsly  vjyqfl
     5  dwuzei  loxrha  vpjjhqf
     6  egs moxia   wbbvk
     7  enzvxg  ozaww   wmiik
     8  fuvks   ph  wpy
     9  gnbjr   phcupa  xsovhv
    10  hdjufth pisza   zuumxy

--------got-------
1sipei
Vpjjhqf
moxIA
wmiik96
9ph32
ozaWW
egs30
Pisza09
jttknol
hdjufTH
ZuumXY
llnsLY
Tatuqun
ikrMP
loxrHA
dwuzei
wbbvk
Xsovhv
PhcuPA
2fuvKS
Wpy09
jxpHN
Bledfoa
VjyqFL
gnbjr
Cdquayr
csglb
8rynLV
azkxBJ
0enzvxg

------------------
Aaron7
  • 277
  • 2
  • 10
  • 1
    Shouldn't you modify the original file? Also, note that `nl` with no other options doesn't number empty lines. – choroba Dec 15 '20 at 23:14
  • How do you know that it doesn't work on the school server? Did you run it and get different output? – that other guy Dec 15 '20 at 23:20
  • Avoid *UUOc*. (*Unnecessary Use Of* `cat`) If you do `cat ...` and you are not concatenating files --- it's likely a *UUOc*. Instead, use redirection as it was intended, e.g `tr .... < $FILE | ...` Don't use all UPPERCASE variable names. Those are reserved for system variables. Something like `fname` is a fine variable name for a filename. If your instructor has given you `FILE` as a variable name -- you may need to recheck what you are learning here. – David C. Rankin Dec 15 '20 at 23:23
  • @DavidC.Rankin None of these issues should affect output, so they are unlikely to be the root cause of this problem. – that other guy Dec 15 '20 at 23:39
  • They were not intended to fix the issue -- that's why they are posted as a comment and not an answer. – David C. Rankin Dec 15 '20 at 23:40
  • 1
    you'll need to expand on the comment *it works ... but not on the school server*; consider updating the question to include the complete contents of `$FILE` as well as the complete output from running your command on the school server – markp-fuso Dec 15 '20 at 23:47
  • 1
    perhaps "school server" means the assignment submission service at school, and not a machine where OP has shell access. – Jasen Dec 15 '20 at 23:54
  • all I can suggest is to re-read the requirements manke sure that your code produces the correct result and nothing superfluous. be aware that $CWD may not be writable. – Jasen Dec 15 '20 at 23:58
  • 1
    There is nothing inherently wrong with your command line. You will create the sorted columns in `file2.txt` and then `nl` will output the lines in `file2.txt` prefixed with numbers My only **guess** is your project either requires you to `rm xaa xab xac file1.txt` to clean up after yourself, or, your format with `nl` isn't correct. Otherwise, your command line works. – David C. Rankin Dec 16 '20 at 00:05
  • I am inclined to interpret "Change this file" to mean that the contents of the original file should be replaced by the transformed results. There might also be issues related to details of the output format, such as column widths and presence / absence of a trailing newline, abd there might be operational issues such as with the working directory being writable by you. We don't have much to go on about the nature of the problem. – John Bollinger Dec 16 '20 at 05:41
  • http://shellcheck.net/ reports a number of common beginner problems with your script. – tripleee Dec 16 '20 at 06:07
  • I completed the query with output from the school server – Aaron7 Dec 16 '20 at 14:42

3 Answers3

1

You can use pr for arranging the columns. No intermediate files are needed:

tr [:upper:] [:lower:] < "${FILE}" \
| tr -d [:digit:] \
| sort \
| pr -t3 \
| nl

or in one line:

tr [:upper:] [:lower:] < "${FILE}" | tr -d [:digit:] | sort | pr -t3 | nl

See: https://linux.die.net/man/1/pr

hek2mgl
  • 152,036
  • 28
  • 249
  • 266
  • Let's go straight there and set the columns so that they are not separated by tabulators but by a space. Somehow I can't find it. Or do it through tr? – Aaron7 Dec 16 '20 at 14:52
  • Hey, that would be `pr -s' ' -t3` .. or `pr -t3s' '` – hek2mgl Dec 16 '20 at 15:41
  • PS: the error you posted, make sure that `$FILE` contains a path to a readable and existing file. – hek2mgl Dec 16 '20 at 21:19
0

An alternative solution with GNU awk:

awk '{ gsub(/[[:digit:]]/,"",$0); # Strip out the numbers
       map[tolower($0)]="" # Create an array with the line at the index in lower case
     } 
 END { PROCINFO["sorted_in"]="@ind_str_asc"; # Set the array sorting order
     for ( i in map ) { 
        printf "%s\t",i;cnt++; # Loop the array and print the entries. Also increment a count variable
        if (cnt==3 || cnt==6 || cnt==9) { printf "\n"  # When the count variable is 3,6 or 9 print a new line
        } 
        if (cnt==10) { printf "\n";exit # If the count is 10 exit
        } 
     } 
  }' file

One liner:

awk '{ gsub(/[[:digit:]]/,"",$0);map[tolower($0)]="" } END { PROCINFO["sorted_in"]="@ind_str_asc";for ( i in map ) { printf "%s\t",i;cnt++;if (cnt==3 || cnt==6 || cnt==9) { printf "\n" } if (cnt==10) { printf "\n";exit } } }' file
Raman Sailopal
  • 12,320
  • 2
  • 11
  • 18
0

I think you've got this part mostly correct but I wrote my own solution to this:

$ cat hash.txt | tr -d '[0-9]' | tr [:upper:] [:lower:] | sort | pr -t3 | nl
     1  aoi         gwsk            sjkdfh
     2  cfehw           hueyu           zhpt
Logan Lee
  • 807
  • 9
  • 21