Bash:在数组中查找非重复元素

时间:2016-08-31 15:08:32

标签: arrays bash duplicates unique

我正在寻找一种在bash中查找数组中非重复元素的方法。

简单示例:

joined_arrays=(CVE-2015-4840 CVE-2015-4840 CVE-2015-4860 CVE-2015-4860 CVE-2016-3598)
<magic>
non_repeated=(CVE-2016-3598)

为了给出上下文,这里的目标是最终得到一系列所有包更新CVE,这些CVE通常不会通过“更新”来获得。由于被排除在主机上我想出这样做的方法是填充3个初步数组:

  • available_updates =()#just&#39; yum update&#39;会提供
  • all_updates =()#include排除的
  • joined_updates =()两个先前数组的#个内容 然后将逻辑应用于joined_updates =(),它只返回恰好包含一次的元素。任何具有两次出现的元素都是可以正常更新的元素,并且不需要在“excluded_updates =()&#39;阵列。

希望这是有道理的。当我输入它时,我想知道从all_updates =()中删除在available_updates =()中找到的所有元素是否更简单,将剩余的元素作为排除的更新。

谢谢!

3 个答案:

答案 0 :(得分:2)

一种纯粹的bash方法是将一个计数器存储在一个关联数组中,然后查找计数器恰好是一个的项目:

declare -A seen=( )                   # create an associative array (requires bash 4)
for item in "${joined_arrays[@]}"; do # iterate over original items
  (( seen[$item] += 1 ))              # increment value associated with item
done

declare -a non_repeated=( )
for item in "${!seen[@]}"; do         # iterate over keys
  if (( ${seen[$item]} == 1 )); then  # if counter for that key is 1...
    non_repeated+=( "$item" )         # ...add that item to the output array.
done

declare -p non_repeated               # print result

另一种方法是,利用标准的文本处理工具,这种方式(但是很忙 - 不能处理包含换行文字的值)方法是:

non_repeated=( )        # setup

# use uniq -c to count; filter for results with a count of 1
while read -r count value; do
  (( count == 1 )) && non_repeated+=( "$value" )
done < <(printf '%s\n' "${joined_arrays[@]}" | sort | uniq -c)

declare -p non_repeated # print result

...或者,甚至更为严格(和buggier,要求数组值在awk中分成一个字段):

readarray -t non_repeated \
  < <(printf '%s\n' "${joined_arrays[@]}" | sort | uniq -c | awk '$1 == 1 { print $2; }'

为了得到答案,我真的应该从@Aaron(他应该得到任何使用此人的人的支持;请注意它保留了与...一起工作的价值观)。 newlines bug),也可以使用uniq -u

readarray -t non_repeated < <(printf '%s\n' "${joined_arrays[@]}" | sort | uniq -u)

答案 1 :(得分:1)

我会依赖const int x = 200; const int y = 100;

uniq选项适用于此确切情况,仅输出唯一身份。它依赖于输入是一个排序的换行分隔的标记列表,因此需要-uIFS

sort

答案 2 :(得分:0)

这是一个基于 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" tools:context=".MainActivity"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/text_view_p1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Player 1 : 0" android:textSize="30sp" /> <TextView android:id="@+id/text_view_p2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/text_view_p1" android:text="Player 2 : 0" android:textSize="30sp" /> <Button android:id="@+id/button_reset" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginEnd="41dp" android:text="reset" /> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/button_00" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:textSize="60sp" /> <Button android:id="@+id/button_01" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:textSize="60sp" /> <Button android:id="@+id/button_02" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_weight="1" android:textSize="60sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/button_10" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:textSize="60sp" /> <Button android:id="@+id/button_11" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:textSize="60sp" /> <Button android:id="@+id/button_12" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:textSize="60sp" /> </LinearLayout> </LinearLayout> </LinearLayout> 的解决方案,不需要from selenium import webdriver from selenium.webdriver.common.keys import Keys import os import urllib.request searchterm = ['3500 Boston St','1415 Bush St','1811 POrtal St'] for i in searchterm: url = "https://www.google.co.in/search?q="+i+"&source=lnms&tbm=isch" browser = webdriver.Chrome(r'C:\Users\XXXX\xxxx\Documents\chromedriver.exe') browser.get(url) header={'User-Agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.134 Safari/537.36"} counter = 0 succounter = 0 if not os.path.exists(i): os.mkdir(i) for x in browser.find_elements_by_xpath('//img[contains(@class,"rg_i Q4LuWd")]'): counter = counter + 1 print("Total Count:", counter) print("Succsessful Count:", succounter) print("URL:", x.get_attribute('src')) img = x.get_attribute('src') new_filename = i+" " +str(counter)+".jpg" try: path = os.path.join(i , i + "_" + str(counter)) path += new_filename urllib.request.urlretrieve(img, path) succounter += 1 except Exception as e: print(e) print(succounter, "pictures succesfully downloaded") browser.close()

awk
sort