追加多个 .txt 文件的名称并重命名串联目标文件

追加多个 .txt 文件的名称并重命名串联目标文件

我是 bash shell 脚本编写的新手,如果已经有人问过这个问题,我深表歉意。

我有多个文件的组合,例如:

USA.txt Florida.txt Miami.txt

我想加入这些文件并创建一个包含所有内容的新文件,例如:

cat *.txt > USA_FLORIDA_MIAMI.txt

在另一种情况下,文件有时具有不同的前缀:

Canada.txt Quebec.txt Montreal.txt

因此,在第二种情况下,输出将为 CANADA_QUEBEC_MONTREAL.txt:

cat *.txt > CANADA_QUEBEC_MONTREAL.txt

对于其他文件的所有组合,依此类推

在第一种情况下,USA.txt Florida.txt Miami.txt 是目录中唯一存在的 .txt 文件。在第二种情况下,它们将被 Canada.txt Quebec.txt Montréal.txt 替换,因此我需要编写一段代码,始终结合当时目录中存在的所有 .txt 文件的前缀信息并将其添加到输出文件的前缀中。这里的变量是国家、州和城市的名称。

关于我可以使用的任何命令有什么建议吗?谢谢

答案1

我想你也可能只使用几个Bash 的参数扩展语法。

基本情况是:

# Use a '_' as IFS value to concatenate arguments while expanding them
IFS=_
# Expand all arguments as "$*", removing their suffix if it matches ".txt" 
names="${*%.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

可用作单行代码,如:

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

或者做了一个函数:

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

包含在脚本中,或source从交互式 shell 中编辑,然后按以下方式使用:

joiner USA.txt Florida.txt Miami.txt

答案2

肮脏,但有效:

#!/bin/bash

files="$@"
new_file=()
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
done

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

mv temp_file.txt $new_name.txt

运行它

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

它将合并文件并根据给定文件创建文件名。

相关内容