I have data in text file in below format


I want output as below

                 Path Name                                         File Name
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/WGS1/CLM/           text1.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/WGS1/CLM/           text2.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/EMP2/               text3.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/ACS1/               text4.txt
  • Welcome to the site. Pleas edit your question to indicate what you already tried. This way you can avoid that contributors point you in a direction you already know doesn't work. Also, do you want to have the "Header" line in the output, or was this only for illustration purposes? – AdminBee Jul 30 '20 at 8:24
  • How wide should the first column be? – Gerard H. Pille Jul 30 '20 at 8:59

You can use awk and column commands like:

awk -F'/' 'BEGIN{print "PathName FileName"}{a="";for(i=2;i<=NF-1;i++){a=a"/"$i};a=a"/";print a"\t"$NF}' file_name  | column -t

It will print like:

PathName                                                  FileName
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/WGS1/CLM/  text1.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/WGS1/CLM/  text2.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/EMP2/      text3.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/ACS1/      text4.txt

If you want to keep the spaces between words Path Name and File Name, then you can delimit by tab instead of space.

awk -F'/' 'BEGIN{print "         Path Name\tFile Name"}{a="";for(i=2;i<=NF-1;i++){a=a"/"$i};a=a"/";print a"\t"$NF}' file_name  | column -t -s $'\t'
         Path Name                                        File Name
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/WGS1/CLM/  text1.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/WGS1/CLM/  text2.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/EMP2/      text3.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/ACS1/      text4.txt
  • Shell scripting? – Gerard H. Pille Jul 30 '20 at 9:09
  • @GerardH.Pille Just one way to do text-processing. – Prvt_Yadav Jul 30 '20 at 9:14
  • 1
    @GerardH.Pille awk is a standard tool when shell scripting and part of posix. – Philip Couling Jul 30 '20 at 9:15
  • @Prvt_Yadav it really helped me in solving the scenario, but the only thing is that i'm getting only one space of gap between Pathname and FIle Names values ... i mean between path and text1.txt .. please help on this – Venkata Abhilash Jul 30 '20 at 9:39
  • @Prvt_Yadav I'm getting once space gap as explained above when i'm sending the output through mail command to my mail ID – Venkata Abhilash Jul 30 '20 at 9:48

ksh only (eg. printf is a shell built-in)

# find the longest path name
while read
  [ $PS -le $MP ] || MP=$PS
done < /tmp/test.txt

# calculate where to put "Path Name"
(( MP++ ))
T="Path Name"
(( SS = ( MP - TS ) / 2 ))
(( SP = ( MP - TS ) % 2 ))
printf "%${SS}s%s%${SS}s%${SP}s %s\n" "" "$T" "" "" "File Name"

# format the input text
while read
  printf "%-${MP}s %s\n" "$P/" "$F"
done < /tmp/test.txt

You may understand why some weaker of heart revert to using POSIX commands.

  • Thanks for the bash only solution. [Q] Wherefrom does the $REPLY shell variable gets its value? – Rakesh Sharma Jul 31 '20 at 3:41
  • When "read" doesn't specify a variable to store what is read, the variable REPLY receives that input. I don't know if my script works with bash, I only use ksh. – Gerard H. Pille Jul 31 '20 at 8:11

Using Perl + column,you could run something along the lines of

perl -pE 'BEGIN{say "Path\tFile\n"} s!.*/\K!\t!' input | column -t

We may employ tbl, groff which is GNU's adaptation of nroff, and the line editor ed.

We first break apart into dirname and basename each line and then inject tbl code at the beginning and end of the file. The tbl code is to center the header columns and left justify the rest.

The tbl utility spits working groff code which groff then operats upon to gets the desired output. The grep is to deletes empty lines.

$ ed -s inp <<\eof | tbl | groff -Tascii | grep .
c c
l l.


                       PATH NAME                           FILE NAME
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/WGS1/CLM/   text1.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/WGS1/CLM/   text2.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/EMP2/       text3.txt
/gpfs/pcenterdata/test/SrcFiles/WCC_CDHP_LITES/ACS1/       text4.txt

Like Prvt_Yadav, you can use awk & column, but awk's "gensub" function can be used to extract the required text.

awk 'BEGIN{print "PathName\tFileName"} {f=gensub(/.*\//,"\\1","1"); p=gensub(/[^/]*$/,"\\1","1"); print p"\t"f}' | column -t

If your source really is this file, you can do it like this:

(echo full_path; cat input) | 
  csv-add-split -c full_path -e / -n parent,name -r |
  csv-cut -c parent,name -S

But if your source is a directory path you can do it like this:

csv-ls -R -c parent,name /gpfs/pcenterdata/test/SrcFiles -S

These commands come from csv-nix-tools (https://github.com/mslusarz/csv-nix-tools).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.