I am new to bash shell scripting, apologies if this was already asked.

I have combinations of multiple files such as:

USA.txt Florida.txt Miami.txt

I would like to join those files and create a new file which contains everything such as:

cat *.txt > USA_FLORIDA_MIAMI.txt

In another case The thing is that some other time the files have a different prefix:

Canada.txt Quebec.txt Montreal.txt

so in this second case, the output will be CANADA_QUEBEC_MONTREAL.txt:


and so on for all the combinations of other files

In the first case scenario, USA.txt Florida.txt Miami.txt are the only .txt files present in the directory. In the second case, they will be replaced by Canada.txt Quebec.txt Montreal.txt so I would need to write a code which all the time combines the information of the prefix of all the .txt files present at that time in the directory and it adds it to the prefix of the output file. The variable here is the name of the Country, State and City.

Any suggestion about any command which I could use? thanks

  • 1
    Are the .txt files to concatenate (e.g., Canada.txt Quebec.txt Montreal.txt or USA.txt Florida.txt Miami.txt) the only .txt files in the directory you wish to work in? Also, must the destination file before the extension be in all uppercase? Please answer in your question after clicking edit. Please do not click on Add Comment as new comments can shove old comments off screen; your information about your PC and installation should all go in the Question so we can all see your findings. – K7AAY Jul 8 at 18:09

I think you might also just use a couple of Bash's Parameter Expansion syntaxes.

The basic thing would be:

# Use a '_' as IFS value to concatenate arguments while expanding them
# Expand all arguments as "$*", removing their suffix if it matches ".txt" 
# Provide all arguments as "$@" to a `cat`, redirected to
# a file named as the concatenated names made uppercase
cat "${@?}" > "${names^^?}.txt"
# The ${@?} syntax prints an error if you don't provide arguments

Usable as a one-liner like in:

bash -c 'IFS=_ names="${*%.txt}"; cat "${@?}" "${names^^?}.txt"' joiner USA.txt Florida.txt Miami.txt

Or made a function:

joiner () {
    local IFS=_
    cat "${@?}" > "${names^^?}.txt"

to be included in a script, or sourceed from your interactive shell, and then used just as in:

joiner USA.txt Florida.txt Miami.txt

dirty, but works:


function join_by { local IFS="$1"; shift; echo "$*"; }

for file in $files; do
    prefix=$(echo $file | awk -F'.' '{print $1}')
    new_file+=( $prefix )
    cat $file >> temp_file.txt

new_name=$(join_by _ "${new_file[@]}")

mv temp_file.txt $new_name.txt

run it with

bash script_name.sh file.txt file2.txt file3.txt ...

it will merge the files and create file name based on given files.

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.