-1

how to split a full file path into a path and a file name without an extension? I'm looking for any files with the extension .conf: find /path -name .conf /path/file1.conf /path/smth/file2.conf /path/smth/file3.conf /path/smth/smth1/.conf ... /path/smt//*.conf

I need the output in string(without extension .conf): /path;file1|path/smth;file2;file3|...

What's the best way to do it? I was thinking of a solution - save the output of the find work to a file and process them in a loop..but maybe there is a more effective way. Sorry for mistakes, I newbie.. Thanx for u feedback, guys!

AleksLi
  • 1
  • 2

4 Answers4

0

since you mentioned .conf, does this help?

kent$ basename -s .conf '/path/smth/file2.conf'
file2

kent$ dirname '/path/smth/file2.conf'          
/path/smth
Kent
  • 189,393
  • 32
  • 233
  • 301
0

To do this in Bash:

find /path/ -type f -name "*.conf"

Note that if you want to do this in a Bash script, you can store /path/ in a variable, for instance one named directory, and change the command like so:

find $directory -type f -name "*.conf"

To do this in Python:

import os
PATH = /path/

test_files = [os.path.join(dp, f) for dp, dn, filenames in os.walk(PATH) for f in filenames
              if os.path.splitext(f)[1] == '.json']

There are some other ways to do this in Python listed here as well

0

bash parameter parsing is easy, fast, and lightweight.

for fp in /path/file1.conf /path/smth/file2.conf /path/smth/file3.conf; do
  p="${fp%/*}"   # %  strips the pattern from the end       (minimal,   non-greedy)
  f="${fp##*/}"  # ## strips the pattern from the beginning (max-match, greedy)
  f="${f%.*}"    # end-strip the already path-cleaned filename to remove extention
  echo "$p, $f"
done
/path, file1
/path/smth, file2
/path/smth, file3

To get what you apparently want as your formatting -

declare -A paths                     # associative array
while read -r fp; do
  p=${fp%/*} f=${fp##*/};            # preparse path and filename
  paths[$p]="${paths[$p]};${f%.*}";  # p as key, stacked/delimited val 
done < file

Then stack/delimit your datasets.

for p in "${!paths[@]}"; do printf "%s|" "$p${paths[$p]}"; done; echo
/path;file1|/path/smth;file2;file3|

For each key, print key/val and a delimiter. echo at end for a newline.

If you don't want the trailing pipe, assign it all to one var in the second loop instead of printing it out, and trim the trailing pipe at the end.

$: for p in "${!paths[@]}"; do out="$out$p${paths[$p]}|"; done; echo "${out%|}"
/path;file1|/path/smth;file2;file3

Some folk will tell you not to use bash for anything this complex. Be aware that it can lead to ugly maintenance, especially if the people maintaining it behind you aren't bash experts and can't be bothered to go RTFM.

If you actually needed that embedded space in your example then your rules are inconsistent and you'll have to explain them.

Paul Hodges
  • 13,382
  • 1
  • 17
  • 36
0

if you have the file paths in a list you can do this using a dictionary with key the path and value the filename

aa=['/path/file1.conf','/path/smth/file2.conf','/path/smth/file3.conf']
f={}
for x in aa:
    temp=x[:-len(".conf")].split("/")
    filename=temp[-1]
    path="/".join(temp[:-1])
    if path in f:
        f[path]=f[path]+","+filename
    else:
        f[path]=filename
result=""
for x in f:
    result=result+str(x)+";"+f[x]+"|"
print(result)
virxen
  • 408
  • 4
  • 12
  • in my env script is working, but on server - error: /path/file1.conf error: No such directory or file syntax error near unexpected token 'temp=x[:len' temp=x[`:-len(".conf")].split("/") why??? – AleksLi Jun 20 '21 at 05:18