Regex 如何在bashshell中读取两个文件的内容并合并到第三个文件中
如何在bash中读取/处理彼此同步的2个文件 我有两个文本文件,其中的行/项数相同。 一个文件是Regex 如何在bashshell中读取两个文件的内容并合并到第三个文件中,regex,bash,awk,sed,pattern-matching,Regex,Bash,Awk,Sed,Pattern Matching,如何在bash中读取/处理彼此同步的2个文件 我有两个文本文件,其中的行/项数相同。 一个文件是 a b c 另一个文件是 1 2 3 如何同步循环这些文件,使a与1,b->2,c->3关联 我以为我可以将文件作为数组读入,然后用索引处理它们,但我的语法/逻辑似乎不正确 这样做f1=$(cat file1)会使f1=a b c。我原以为执行f1=($(cat file1))会使它成为一个数组,但它使f1=a因此没有数组可供我处理 如果有人想知道我的乱码是什么: hostnames=($(ca
a
b
c
另一个文件是
1
2
3
如何同步循环这些文件,使a
与1
,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
使用paste
()组合文件,然后一次处理组合文件的一行:
paste file1 file2 |
while read -r first second
do
echo $first
echo $second
done
您可以使用:
while read -r var_from_file1 && read -r var_from_file2 <&3; do
echo "$var_from_file1 ---> $var_from_file2"
done <file1 3<file2
GNU代码:
- 前面有
:file1
sed -r 's#(.*)#s/(.*)/\1 \\1/;$!n#' file1|sed -rf - file2
或sed -r 's#(.*)#s/(.*)/\\1 \1/;$!n#' file2|sed -rf - file1
- 前面有
:file2
sed -r 's#(.*)#s/(.*)/\1 \\1/;$!n#' file1|sed -rf - 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 a 1 b 2 C3 d 4 e 5 f 6 g 7 你的方式:
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
host\u file=host1
角色\文件=角色1
主机名=($(cat$host_文件))
角色=($(类别$role_文件))
((cnt=${{主机名[@]}-1))
echo“cnt是$cnt”
对于((i=0;i两个示例):
更好的是:——)
..输出总是:
a 1
b 2
c 3
纯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
IFS=$”\n
hostnames=($)(这个问题的一个简洁而灵活的解决方案是核心utilpr
:
# 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
。希望输入中没有斜杠。:-)不过,请查看粘贴文件1文件2
。@chirlu您是对的,如果斜杠必须更改正则表达式(稍微):-)要用文件内容填充数组,我将$IFS
设置为\n
并使用命令数组=($(不幸的是,数组中的字段将不包含文件中的行,而是单词!您最好使用mapfile
,因此:mapfile-t hostnames
,而且效率更高!时间(1)在使用30000行文件时,显示没有显著差异。开关-t删除了尾随的换行符。对我来说,两个版本中的数组内容都是相同的。我是否忽略了什么?它在我的系统上运行,可能比您的系统更旧、更慢。此外,$(…)
运行子shell,而mapfile
不运行子shell。此外,a=($(
将创建一个数组,其中字段是文件的单词,而不是它的行。谢谢。通过设置IFS可以解决单词问题。选择mapfile可以留给读者。这绝对是最好的答案!+1
。
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
# space separated
$ pr -mts' ' file1 file2
a 1
b 2
c 3
# -> separated
$ pr -mts' -> ' file1 file2
a -> 1
b -> 2
c -> 3