在Shell中使用FOR循环创建多个文件

在Shell中使用FOR循环创建多个文件,shell,Shell,我有两个文件。其中一个包含需要创建的文件名列表,另一个包含文件名和内容(用制表符分隔),我需要如下所示: File 1: AAA.txt BBB.txt CCC.txt DDD.txt File 2: AAA.txt Select * from abc; AAA.txt Delete from abc; CCC.txt select * from xyz; DDD.txt select * from efg; 现在我需要创建AAA.txt文件(如文件1所

我有两个文件。其中一个包含需要创建的文件名列表,另一个包含文件名和内容(用制表符分隔),我需要如下所示:

File 1:

AAA.txt   
BBB.txt  
CCC.txt  
DDD.txt

File 2:

AAA.txt  Select * from abc;  
AAA.txt  Delete from abc;  
CCC.txt  select * from xyz;  
DDD.txt  select * from efg;
现在我需要创建AAA.txt文件(如文件1所示),并将相应的内容放入文件2中。请注意,文件2中每个文件的行数可能不同,但将按文件名分组


谢谢

在标准(POSIX)shell中有一种方法:

xargs touch<“文件1”
读取文件名行时;做
printf“%s\n”“$line”>>$filename
完成<“文件2”

使用
awk

awk -F'  ' 'NR == FNR { a[$1] = a[$1] $2 ORS } { t = $0; sub(/[[:blank:]]+$/, "", t) } t in a { printf "%s", a[t] > t }' file2 file1
或者更安全,即使数据(第二列)有两个空格:

awk 'BEGIN { FS = OFS = "  " } NR == FNR { t = $1; $1 = ""; sub(/^[[:blank:]]+/, ""); a[t] = a[t] $0 ORS } { t = $0; sub(/[[:blank:]]+$/, "", t) } t in a { printf "%s", a[t] > t }' file2 file1
并使用
bash

#!/bin/bash
FILE1=$1
FILE2=$2
[ -n "$BASH_VERSION" ] && [[ BASH_VERSINFO -ge 4 ]] || exit 1
shopt -s extglob
declare -A MAP=()
declare -A FLAGS=()
IFS=$' \t\n'  ## Use normal IFS.
while read -r LINE; do
    NAME=${LINE%%  *}
    DATA=${LINE#*  }
    MAP[$NAME]=${MAP[$NAME]}$DATA$'\n'
done < "$FILE2"
while read -r NAME; do
    (( ! FLAGS[$NAME]++ )) && : > "$NAME"
    echo -n "${MAP[$NAME]}" >> "$NAME"
done < "$FILE1"

我在试着理解你的代码。文件1中的代码看起来可疑。据我所知,没有任何语言会使用这种语法。我假设这就是输入。文件2中的代码看起来像
sql
语句,但select语句之前的代码使我感到不舒服。请重新格式化您的代码,我将调试您的代码并发布回复。您好@alvits,文件1包含扩展名为.sh(而不是.txt)的所有文件名,文件2肯定包含文件1中给出的所有文件名的条目。实际上,我错误地错过了BBB的一个条目。第一个文件对于创建“缺少”的文件非常有用,例如BBB.txt。在while循环之前,您可以
xargs touch
@jlliagre。。工作正常。非常感谢您的帮助,希望内容不包含双空格。
#!/bin/bash
FILE1=$1
FILE2=$2
[ -n "$BASH_VERSION" ] && [[ BASH_VERSINFO -ge 4 ]] || exit 1
shopt -s extglob
declare -A MAP=()
declare -A FLAGS=()
IFS=$' \t\n'  ## Use normal IFS.
while read -r LINE; do
    NAME=${LINE%%  *}
    DATA=${LINE#*  }
    MAP[$NAME]=${MAP[$NAME]}$DATA$'\n'
done < "$FILE2"
while read -r NAME; do
    (( ! FLAGS[$NAME]++ )) && : > "$NAME"
    echo -n "${MAP[$NAME]}" >> "$NAME"
done < "$FILE1"
bash script.sh file1 file2