![追加多个 .txt 文件的名称并重命名串联目标文件](https://linux22.com/image/156749/%E8%BF%BD%E5%8A%A0%E5%A4%9A%E4%B8%AA%20.txt%20%E6%96%87%E4%BB%B6%E7%9A%84%E5%90%8D%E7%A7%B0%E5%B9%B6%E9%87%8D%E5%91%BD%E5%90%8D%E4%B8%B2%E8%81%94%E7%9B%AE%E6%A0%87%E6%96%87%E4%BB%B6.png)
我是 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 ...
它将合并文件并根据给定文件创建文件名。