1

I have files in folder. which look like

1232_2019_02_09_12_29_29.txt
1232_2019_02_09_12_29_55.txt

I want to extract 2019_02_09_12_29_29 & 2019_02_09_12_29_55 from file name and convert into 2019-02-09-122929 & 2019-02-09-122955.

#!/bin/sh

path=$1

if [[ -z $1 ]];then
        echo "USAGE:: Argument missing, supply full path to list all files"
        exit 1
fi

if [ -f $path/all_files.txt ] ; then
    rm -f $path/all_files.txt
fi

ls -l $path | grep -v "^d" | awk '{print $9}' > $path/all_files.txt

while read -r line
do
        line=${line##*/}
#       echo "${line%"/}"
        ex1=`awk -F'|' '{print substr($1,length($1)-22, 19)}'`
#       ex2=`awk -F'|' '{print substr($1,length($1)-19, 10)}'`
        echo $ex1
        ex2=$(echo $ex1 | cut -c 1-10)
        echo $ex2
        ex3=$(echo $ex1 | cut -c 12-20)
        echo $ex3
done <$path/all_files.txt

But this code is not giving me desired output.

Kusalananda
  • 333,661
Geeme
  • 121

5 Answers5

2

You can replace entire while loop with this line:

awk -F'[._]' '{print $2"-"$3"-"$4"-"$5$6$7}' $path/all_files.txt

If you want to keep the extension of the files (.txt) you should use command like this:

awk -F_ '{print $2"-"$3"-"$4"-"$5$6$7}' $path/all_files.txt
Romeo Ninov
  • 17,484
0

I don't understand why you get downvote.
You are new contributor.
You give your research/effort.
So you are welcome and sorry for bad english.

First, you write #!/bin/sh and after you use if [[ -z $1 ]]
Not all sh shell handle [[ , so use if [ -z "$1" ]
Always quote your var like "$1"
Don't use ls in a script
You look for *.txt files so don't name your file all_files.txt, name it with .log
Don't use grep cut ... if you use awk or sed because awk and sed can handle that alone.
Don't read a file line by line when you use awk which can do that.

You can try this way :

#!/bin/sh

if [ -z $1 ];then
    echo "USAGE:: Argument missing, supply full path to list all files"
    exit 1
fi

log="$1/all_files.log"

if [ -f "$log" ] ; then
  rm -f "$log"
else
  echo "no file to rm"
fi

echo "with gnu sed"
find "$1" -maxdepth 1 -type f -name '*.txt' |
  sed 's/[^_]*_//;s/_//4g;s/_/-/g' # > "$log"

echo "with awk"
find "$1" -maxdepth 1 -type f -name '*.txt' |
  awk -F\_ '{for(i=2;i<5;i++)a=a$i"-";a=a$(i++)$(i++)$i;print a;a=""}' # > "$log"
ctac_
  • 1,960
0
#!/bin/sh

# Given arguments:
#    A single directory path to somewhere that has *.txt files.
# Assumption:
#    All *.txt files have filenames on the format XXXX_YYYY_MM_DD_hh_mm_ss.txt.
# Output:
#    The YYYY_MM_DD_hh_mm_ss part of each filename on the format YYYY-MM-DD-hhmmss.

# Set the positional parameters to the list of pathnames in the given directory.
set -- "$1"/*.txt

# Turn off filename globbing and set field splitting delimiter to an underscore.
set -f
IFS='_'

# Loop over the positional parameters generated above.
for pathname do
    # If this is not a regular file (or a symbolic link to one), skip.
    [ ! -f "$pathname" ] && continue

    # Get the filename portion of the pathname and delete the filename suffix.
    filename=$( basename "$pathname" .txt )

    # Delete the bit up to the first underscore in the remaining string.
    filename=${filename#*_}

    # Rely on the shell's word splitting to split the sting up into
    # separate words and then use printf to assemble the words inte the
    # format that we want.
    printf '%s-%s-%s-%s%s%s\n' $filename
done

Testing:

$ ls dir
1232_2019_02_09_12_29_29.txt  1232_2019_02_09_12_29_55.txt
$ sh script.sh dir
2019-02-09-122929
2019-02-09-122955

Related:

Kusalananda
  • 333,661
0

I have used below method to achieve the same

awk -F "_" 'OFS="-"{$1="";print $0}' filename|sed "s/\..*//g"| sed 's/^-//g'| awk '{print substr($1,1,13)substr($1,15,2)substr($1,18)}'

output

2019-02-09-122929
2019-02-09-122955
0

Using sed:

sed 's/^[^_]*_\(.*\)\..*$/\1/;y/_/-/;s/-\([^-]*\)-\([^-]*\)$/\1\2/' \
     $path/all_files.txt 
agc
  • 7,223