问题是我想在多列的前面附加第一列数据,同时保持它们对齐
当我将它们单独重定向到Cmain时,循环也会按照我的意愿行事;但我需要对他们两个人这样做#copies first column of original car file to format the atom numbers
FC=$(awk '{for (i=6; i<=21 ; i++)
if (NR >= 6 && NR == i)
print $1}' $carf)
#copies and formats the rest of the columns from the .incoor file and sets to variable Col
col=$(awk '{for (j=6; j <= 21 ; j++)
if (NR >= 6 && NR == j)
printf "%13.8f\t%12.8f\t%12.8f%s%s%s%s%4.3f\n", $2, $3, $4,
" XXXX", " 1", " xx"," " $1" ", " 0.000"}' $coor)
这是出问题的地方
#echos variables and appends to Cmain
echo " $FC $col" >> Cmain
正在发生的事情的例子;由于某种原因,它需要第二组列并将它们向下移动,并将第一行移动...就像我说当我单独执行它们时列对齐并且一切都是桃子...除了我缺少第一列数据
U1
U2
U3
U4
C1
C2
C3
C4
U5
U6
U7
U8
C5
C6
C7
C8 0.00000000 0.00000000 0.00000000 XXXX 1 xx U 0.000
0.00000000 4.43785037 4.86047726 XXXX 1 xx U 0.000
4.86047726 0.00000000 4.86047726 XXXX 1 xx U 0.000
4.86047726 4.43785037 0.00000000 XXXX 1 xx U 0.000
4.86047726 4.43785037 4.86047726 XXXX 1 xx C 0.000
4.86047726 0.00000000 0.00000000 XXXX 1 xx C 0.000
0.00000000 0.00000000 4.86047726 XXXX 1 xx C 0.000
0.00000000 8.87570074 0.00000000 XXXX 1 xx U 0.000
0.00000000 13.31355111 4.86047726 XXXX 1 xx U 0.000
4.86047726 8.87570074 4.86047726 XXXX 1 xx U 0.000
4.86047726 13.31355111 0.00000000 XXXX 1 xx U 0.000
4.86047726 13.31355111 4.86047726 XXXX 1 xx C 0.000
4.86047726 8.87570074 0.00000000 XXXX 1 xx C 0.000
0.00000000 13.31355111 0.00000000 XXXX 1 xx C 0.000
0.00000000 8.87570074 4.86047726 XXXX 1 xx C 0.000
〜
我想要的是
U1 0.00000000 0.00000 etc
U2 0.00000000 4.43785037 4.86047726 .......
答案 0 :(得分:2)
您正在寻找paste
(1)命令。 echo
无法将一个字符串拼接成另一个字符串(这看起来就像你要找的那样;在字符串2中的每一个新行之前,插入字符串1中的下一行)。
paste
适用于文件,而不是字符串,但在Bash中,这很容易解决;只需使用process substitution。
#!/bin/bash
# Refactored into a function for maintainability and legibility
# Maybe you want to factor out the magical constants 6 and 21 somehow as well?
atoms () {
awk '# Simplified script; apparently, you simply want lines 6 through 21
NR==6,NR==21 { print $1 }' "$@"
}
# Ditto
cols () {
awk '# Simplified this script as well
NR==6,NR==21 {
printf "%13.8f\t%12.8f\t%12.8f%s%s%s%s%4.3f\n", $2, $3, $4,
" XXXX", " 1", " xx"," " $1" ", " 0.000"}' "$@"
}
paste <(atoms "$carf") <(cols "$coor")
如果文件很大,您可以在第21行退出后节省大量时间。
NR==22 { exit }
答案 1 :(得分:1)
对于每个文件的每个行,您的AWK脚本从6到21计数。我不认为这是必要的。我认为你要做的只是测试线号是否在该范围内。这是我的意思的一个例子:
FC=$(awk 'NR >= 6 && NR <=21)
print $1}' $carf)
但是,您真正需要做的是组合两个AWK脚本,保存数组中第一个文件的值,并在打印第二个文件中的值时打印数组中的值。
awk 'FNR == NR && FNR >= 6 && FNR <= 21 { # first file
carf[FNR] = $1
}
FNR == NR {
next
}
FNR >= 6 && FNR <= 21 { # second file
printf "%-4s%13.8f\t%12.8f\t%12.8f%s%s%s%s%4.3f\n", carf[FNR], $2, $3, $4,
" XXXX", " 1", " xx"," " $1" ", " 0.000"
}' "$carf" "$coor"
请注意,没有echo
(或paste
)。
除非您的输出中确实需要制表符,否则可以将它们保留并调整字段宽度,以便为您提供所需的输出对齐。