如何在循环shell中使用许多变量

时间:2014-06-08 20:12:35

标签: bash shell

for ((i=1;; i++)); do
    read "d$i" || break;
done < /home/marcin/workspace/bake/source/ns-3.19/RESULTS/macaddr.txt
echo "$d1"
echo "$d2"
echo "$d5"
for ((j=1;j<=5; j++)); do
    echo "$d$j" || break;
done

这是我的代码,但问题是我无法显示我maaddr.txt文件中的所有MAC地址。如果我只使用echo "$d1"echo "$d2",则可以正常使用。我想把它放到循环中,但echo "$d$j"似乎不起作用。


确定工作正常,但当我把它放入整个代码时,我无法生成我需要的文件。使用循环(使用mac_adresses)后,整个代码仅适用于存储在macaddr.txt中的最后一个mac_address。

> #!/bin/sh
> 
> #SETTING parameters to generate feature vectors
> 
> #set the directory of the initial .pcap files" files=/home/marcin/workspace/bake/source/ns-3.19/RESULTS/TRAFFIC_LIGHTS/*
> udp_fil_dir=/home/marcin/workspace/bake/source/ns-3.19/RESULTS/TRAFFIC_LIGHTS/_udp_filtered/*
> mac_sorted_dir=/home/marcin/workspace/bake/source/ns-3.19/RESULTS/TRAFFIC_LIGHTS/_udp_filtered/_MAC_sorted/*
> 
> #set <src> for source mac address (outcoming packets) or <dst> for destination source mac address (incoming packets) ether_direction=src
> 
> #FILTERING only UDP packets from pcap file stored in a specific folder
> 
> printf "...FILTERING only UDP packets from pcap files stored in a
> specific folder...\n"
> 
> for f in $files do tshark -Y "udp&&!aodv" -r "$f" -w
> ""$f"_udp_filtered".pcap
> #mergecap -w all_pcaps *.pcap mkdir /home/marcin/workspace/bake/source/ns-3.19/RESULTS/TRAFFIC_LIGHTS/_udp_filtered
> mv  ""$f"_udp_filtered".pcap
> /home/marcin/workspace/bake/source/ns-3.19/RESULTS/TRAFFIC_LIGHTS/_udp_filtered
> done
> 
> for g in $udp_fil_dir do
> #FILTERING packets with a source/destination mac address set in the parameters and writing the results into the new .pcap file printf
> "...FILTERING packets with a source mac adress: "$mac_addr"...\n" 
> 
> #max=5
> #for ((i=1;i<=$max; i++)); 
> #do
> 
> #storing all the macaddresses from the macaddr.txt file
> 
> IFS=$'\n' read -d '' -r -a mac_addresses <
> '/home/marcin/workspace/bake/source/ns-3.19/RESULTS/macaddr.txt' for
> mac_address in "${mac_addresses[@]}" do
> 
> tcpdump ether "$ether_direction" "${mac_address}" -tt -r "$g" -w
> ""$g"_MAC_sort".pcap
> #echo "$ether_direction" "$d$i" done
> #done
> #CONVERTING .pcap file into the .txt file printf "...CONVERTING .pcap file into the .txt file...\n"
> 
> #tshark -r ""$g"_MAC_sort".pcap > ""$g"_MAC_sort".txt  tcpdump -e -r ""$g"_MAC_sort".pcap > ""$g"_MAC_sort".txt 
> #moving all the files to another directory
> 
> mkdir
> /home/marcin/workspace/bake/source/ns-3.19/RESULTS/TRAFFIC_LIGHTS/_udp_filtered/_MAC_sorted
> mv  ""$g"_MAC_sort".txt
> /home/marcin/workspace/bake/source/ns-3.19/RESULTS/TRAFFIC_LIGHTS/_udp_filtered/_MAC_sorted
> done
> 
> for h in $mac_sorted_dir do
> #ADDING a string //filename// at the beginning of each line printf "...ADDING a string //filename// at the beginning of each line...\n"
> 
> export fspec=./"$h"  fname=`basename $fspec` echo $fname
> 
> #awk 'BEGIN{print "'$fname'"}'  awk '{print "'$fname'" $0;}' "$h" > ""$h"_index".txt mkdir
> /home/marcin/workspace/bake/source/ns-3.19/RESULTS/TRAFFIC_LIGHTS/_udp_filtered/_MAC_sorted/indexed
> mv ""$h"_index".txt
> /home/marcin/workspace/bake/source/ns-3.19/RESULTS/TRAFFIC_LIGHTS/_udp_filtered/_MAC_sorted/indexed
> done
> 
> cd
> /home/marcin/workspace/bake/source/ns-3.19/RESULTS/TRAFFIC_LIGHTS/_udp_filtered/_MAC_sorted/indexed
> cat * >> "$ether_direction"_"${mac_address}"_final.txt
> 
> #COUNTING the lines printf "...COUNTING the lines...\n"
> 
> # function storing list of all files in variable files get_files () {   files="`ls "$ether_direction"_"${mac_address}"_final.txt`"
> #################INPUT TEXT FILE //"$ether_direction"_"$mac_addr"_final.txt }
> 
> # function counting the number of lines in a file count_lines () {   f=$1  # 1st argument is filename   l=`wc -l $f | sed
> 's/^\([0-9]*\).*$/\1/'` # number of lines }
> 
> # the script should be called without arguments if [ $# -ge 1 ] then   echo "Usage: $0 "   exit 1 fi
> 
> # split by newline IFS=$'\012'
> 
> echo "$0 counts the lines of code"  l=0 n=0 s=0
> # call a function to get a list of files get_files
> # iterate over this list for f in $files do
>         # call a function to count the lines
>         count_lines $f
>         #echo "$f: $l"loc     # store filename in an array    file[$n]=$f     # store number of lines in an array     lines[$n]=$l    # increase counter
>         n=$[ $n + 1 ]     # increase sum of all lines
>         s=$[ $s + $l ] done
> 
> #echo "$n files in total, with $s lines in total"
> 
> #GIVING a final result: 
> 
> printf "***************************************************\n" printf
> "NUMBER OF LINES:"$s"\n" printf
> "***************************************************\n"

2 个答案:

答案 0 :(得分:3)

只需使用数组。假设Bash≥4(嘿,我们在2014年,你真的不应该再使用Bash 3了):

mapfile -t ary < /home/marcin/workspace/bake/source/ns-3.19/RESULTS/macaddr.txt
for m in "${ary[@]}"; do
    echo "$m"
done

否则,如果你真的想坚持你的笨重方式,使用间接扩展,但我不推荐它:

for ((j=1;j<=5; j++)); do
    indirect=d$j
    echo "${!indirect}"
done

答案 1 :(得分:0)

使用您的代码,我会尝试使用"$d"${j}

for ((i=1;; i++)); do
    read "d$i" || break;
done < /home/marcin/workspace/bake/source/ns-3.19/RESULTS/macaddr.txt
echo "$d1"
echo "$d2"
echo "$d5"
for ((j=1;j<=5; j++)); do
    echo "$d"${j} || break;
done

但是,如果您只是将文件读入真正的BASH数组然后循环使用,那么您的生活可能会更容易:

IFS=$'\n' read -d '' -r -a mac_addresses < '/home/marcin/workspace/bake/source/ns-3.19/RESULTS/macaddr.txt'
printf "%s\n" "${mac_addresses[0]}"
printf "%s\n" "${mac_addresses[1]}"
printf "%s\n" "${mac_addresses[2]}"
printf "%s\n" "${mac_addresses[3]}"
printf "%s\n" "${mac_addresses[4]}"
printf "%s\n" "${mac_addresses[5]}"

你可以像这样回复所有mac_addresses

echo "${mac_addresses[@]}"

或者像这样循环遍历:

for mac_address in "${mac_addresses[@]}"
do
  echo ${mac_address}
done