如何从两个文件中读取内容并合并到bash shell中的第三个文件中

时间:2013-06-21 19:50:35

标签: regex bash awk sed pattern-matching

如何在bash中相互同步读取/处理2个文件?

我有2个文本文件,其中包含相同数量的行/项。 一个文件是

a
b
c

另一个文件是

1
2
3

如何同步循环浏览这些文件,以便a1相关联,b-> 2,c-> 3?

我认为我可以将文件作为数组读入,然后使用索引处理它们,但似乎我的语法/逻辑不正确。

f1=$(cat file1)这样做f1 = a b c。我认为做f1=($(cat file1))会使它成为一个数组,但它会生成f1=a因此没有数组供我处理。

如果有人想知道我的混乱代码是什么:

hostnames=($(cat $host_file))  
# trying to read in as an array, which apparently is incorrect
roles=($(cat $role_file))

for i in {0..3}
do
   echo ${hostnames[$i]}   
   # wanted to iterate through each element in the file/array
   # but there is only one object instead of N objects
   echo ${roles[$i]}
done

7 个答案:

答案 0 :(得分:17)

您可以使用 file descriptors

while read -r var_from_file1 && read -r var_from_file2 <&3; do 
    echo "$var_from_file1 ---> $var_from_file2"
done <file1 3<file2

输出:

a ---> 1
b ---> 2
c ---> 3

答案 1 :(得分:10)

使用pasteinvocation)合并文件,然后一次处理合并文件的一行:

paste file1 file2 |
while read -r first second
do
  echo $first
  echo $second
done

答案 2 :(得分:2)

GNU代码

  • 前面有file1

    sed -r 's#(.*)#s/(.*)/\1 \\1/;$!n#' file1|sed -rf - file2
    

  • 前面有file2

    sed -r 's#(.*)#s/(.*)/\\1 \1/;$!n#' file2|sed -rf - file1
    

两者都会产生相同的输出:

a 1
b 2
c 3
d 4
e 5
f 6
g 7

答案 3 :(得分:2)

你的方式:

host_file=host1
role_file=role1

hostnames=(  $(cat $host_file) )  
roles=( $(cat $role_file)  )
(( cnt = ${#hostnames[@]}  -1 ))
echo "cnt is $cnt"
for (( i=0;i<=$cnt;i++))
do
  echo "${hostnames[$i]} ->    ${roles[$i]}"
done

答案 4 :(得分:2)

的两个例子:

awk '{print $0, NR}' file1

和 - 更好: - )

awk 'NR==FNR {a[NR]=$0;next};{print a[FNR], $0}' file1 file2

..输出总是:

a 1
b 2
c 3

答案 5 :(得分:2)

这个问题的简明而灵活的解决方案是core-util pr

# space separated
$ pr -mts' ' file1 file2
a 1
b 2
c 3

# -> separated
$ pr -mts' -> ' file1 file2
a -> 1
b -> 2
c -> 3

有关详细信息,请参阅man pr

答案 6 :(得分:0)

Pure Bash:

IFS=$'\n'
hostnames=( $( <hostnames.txt ) )
roles=( $( <roles.txt ) )

for idx in ${!hostnames[@]}; do    # loop over array indices
  echo -e "${hostnames[idx]} ${roles[idx]}"
done

或在gniourf_gniourf的评论之后

mapfile -t hostnames < hostnames.txt
mapfile -t roles < roles.txt

for idx in ${!hostnames[@]}; do              # loop over array indices
  echo -e "'${hostnames[idx]}' '${roles[idx]}'"
done
相关问题