I have a list of files named:

file (1).txt
file (2).txt
file (7).txt


Where the greater (number) is the last file updated, but some intermediate numbers might be missing and there are other files on the directory as well.

How to check if there is a "duplicate" file, and if there is, how to copy the content of file (maxnumer).txt to file.txt, and remove all file (*).txt files.

I tried listing them with ls -t file*(*)*.txt and then make a for loop but it gives me an error (ls): bash:syntax error near unexpected token '('

  • What was the error? What was your loop? – Kusalananda Jun 29 '18 at 18:21
  • ls gives me the error, i haven't yet got to the for loop – kurokirasama Jun 29 '18 at 18:23

Assuming that the timestamps are not reliable, we'd like to find the file that has the largest number in the parenthesis towards the end of the filename.

Doing that:



if [ -z "$prefix" ]; then
    printf 'Usage: %s prefix [ suffix ]\n' "$0" >&2
    exit 1


for filename in "$prefix ("*")$suffix"; do
    [ ! -f "$filename" ] && continue

    num=${filename##*\(}    # "file (xx).txt" --> "xx).txt"
    num=${num%\)*}          # "xx).txt" --> "xx"

    # if no max number yet, or if current number is higher, update max
    if [ -z "$max" ] || [ "$num" -gt "$max" ]; then

# if we have a max number, use it to rename the file and then remove the other files
if [ -n "$max" ]; then
    printf 'Would move %s to %s\n' "$prefix ($max)$suffix" "$prefix$suffix"
    # mv "$prefix ($max)$suffix" "$prefix$suffix"
    printf 'Would remove %s\n' "$prefix ("*")$suffix"
    # rm "$prefix ("*")$suffix"
    printf 'Found no files matching "%s (*)%s"\n' "$prefix" "$suffix"

Running it:

$ tree
|-- file (1).txt
|-- file (2).txt
|-- file (7).txt
|-- file.list
|-- file.txt
`-- script.sh

0 directory, 6 files

$ sh script.sh file .txt
Would move file (7).txt to file.txt
Would remove file (1).txt
Would remove file (2).txt
Would remove file (7).txt

(remove the commented out mv and rm to actually modify files)

This would fail for filenames such as file (2) (30).txt (these would also be matched) as it assumes that all filenames follow the pattern prefix (NN)suffix where NN is an integer.

| improve this answer | |
  • 1
    last if get executed even if there are no (*) files... – kurokirasama Jun 29 '18 at 22:46
  • maybe it is because i'm triyng to set the files as an input file=$1. Does that chages the rest of the script? I'm trying with if [[ $max == ?(-)+([0-9]) ]] – kurokirasama Jun 29 '18 at 23:12
  • @kurokirasama See update answer. I'm not sure what you're trying to achieve with that test in your previous comment. – Kusalananda Jun 30 '18 at 6:37

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.